@hkyhy/marsun-components-core 0.1.82 → 0.1.98

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 (285) hide show
  1. package/dist/components/Audit/AuditLogList.d.ts +27 -0
  2. package/dist/components/Audit/AuditLogList.js +272 -0
  3. package/dist/components/Audit/AuditLogList.js.map +1 -0
  4. package/dist/components/Audit/formatAuditCurl.d.ts +27 -0
  5. package/dist/components/Audit/formatAuditCurl.js +115 -0
  6. package/dist/components/Audit/formatAuditCurl.js.map +1 -0
  7. package/dist/components/Audit/formatAuditJson.d.ts +15 -0
  8. package/dist/components/Audit/formatAuditJson.js +135 -0
  9. package/dist/components/Audit/formatAuditJson.js.map +1 -0
  10. package/dist/components/Audit/index.d.ts +3 -0
  11. package/dist/components/Audit/style.module.scss.js +30 -0
  12. package/dist/components/Audit/style.module.scss.js.map +1 -0
  13. package/dist/components/Audit/types.d.ts +39 -0
  14. package/dist/components/Editor/RichTextEditor/RichTextEditor.d.ts +24 -0
  15. package/dist/components/Editor/RichTextEditor/RichTextEditor.js +93 -0
  16. package/dist/components/Editor/RichTextEditor/RichTextEditor.js.map +1 -0
  17. package/dist/components/Editor/RichTextEditor/index.d.ts +2 -0
  18. package/dist/components/Editor/RichTextEditor/style.module.scss.js +11 -0
  19. package/dist/components/Editor/RichTextEditor/style.module.scss.js.map +1 -0
  20. package/dist/components/Editor/VariablePicker.d.ts +19 -0
  21. package/dist/components/Editor/VariablePicker.js +55 -0
  22. package/dist/components/Editor/VariablePicker.js.map +1 -0
  23. package/dist/components/Editor/index.d.ts +7 -0
  24. package/dist/components/Editor/index.js +21 -0
  25. package/dist/components/Editor/index.js.map +1 -0
  26. package/dist/components/Editor/msgVarTokenPlugin.d.ts +13 -0
  27. package/dist/components/Editor/msgVarTokenPlugin.js +94 -0
  28. package/dist/components/Editor/msgVarTokenPlugin.js.map +1 -0
  29. package/dist/components/Editor/variableMention.d.ts +37 -0
  30. package/dist/components/Editor/variableMention.js +64 -0
  31. package/dist/components/Editor/variableMention.js.map +1 -0
  32. package/dist/components/FormInfo/RichTextField/index.d.ts +21 -0
  33. package/dist/components/FormInfo/RichTextField/index.js +82 -0
  34. package/dist/components/FormInfo/RichTextField/index.js.map +1 -0
  35. package/dist/components/FormInfo/RichTextField/style.module.scss.js +9 -0
  36. package/dist/components/FormInfo/RichTextField/style.module.scss.js.map +1 -0
  37. package/dist/components/FormInfo/VariableMentionInput/index.d.ts +17 -0
  38. package/dist/components/FormInfo/VariableMentionInput/index.js +73 -0
  39. package/dist/components/FormInfo/VariableMentionInput/index.js.map +1 -0
  40. package/dist/components/FormInfo/VariableMentionInput/style.module.scss.js +11 -0
  41. package/dist/components/FormInfo/VariableMentionInput/style.module.scss.js.map +1 -0
  42. package/dist/components/FormInfo/fields.d.ts +5 -0
  43. package/dist/components/FormInfo/fields.js +32 -23
  44. package/dist/components/FormInfo/fields.js.map +1 -1
  45. package/dist/components/FormInfo/index.d.ts +4 -0
  46. package/dist/components/StateBar/StateBar.d.ts +19 -6
  47. package/dist/components/StateBar/StateBar.js +87 -50
  48. package/dist/components/StateBar/StateBar.js.map +1 -1
  49. package/dist/components/StateBar/style.module.scss.js +13 -10
  50. package/dist/components/StateBar/style.module.scss.js.map +1 -1
  51. package/dist/components/Table/ResizableHeaderCell.js +37 -38
  52. package/dist/components/Table/ResizableHeaderCell.js.map +1 -1
  53. package/dist/components/Table/Table.js +88 -89
  54. package/dist/components/Table/Table.js.map +1 -1
  55. package/dist/components/Table/columnConfigUtils.d.ts +1 -1
  56. package/dist/components/Table/columnConfigUtils.js.map +1 -1
  57. package/dist/components/Table/style.module.scss.js +34 -34
  58. package/dist/components/Tools/Inbox/InboxBell/InboxBell.d.ts +45 -0
  59. package/dist/components/Tools/Inbox/InboxBell/InboxBell.js +156 -0
  60. package/dist/components/Tools/Inbox/InboxBell/InboxBell.js.map +1 -0
  61. package/dist/components/Tools/Inbox/InboxBell/index.d.ts +2 -0
  62. package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js +30 -0
  63. package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js.map +1 -0
  64. package/dist/components/Tools/Inbox/index.d.ts +2 -0
  65. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/List/columns.d.ts +8 -0
  66. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/List/columns.js +56 -0
  67. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/List/columns.js.map +1 -0
  68. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.d.ts +8 -0
  69. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.js +216 -0
  70. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.js.map +1 -0
  71. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.d.ts +26 -0
  72. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js +190 -0
  73. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js.map +1 -0
  74. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/index.d.ts +3 -0
  75. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/style.module.scss.js +12 -0
  76. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/style.module.scss.js.map +1 -0
  77. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.d.ts +76 -0
  78. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.js +26 -0
  79. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.js.map +1 -0
  80. package/dist/components/Tools/MessageCenter/index.d.ts +3 -0
  81. package/dist/components/Tools/MessageCenter/utils/templateCode.d.ts +8 -0
  82. package/dist/components/Tools/MessageCenter/utils/templateCode.js +25 -0
  83. package/dist/components/Tools/MessageCenter/utils/templateCode.js.map +1 -0
  84. package/dist/components/Tools/index.d.ts +5 -0
  85. package/dist/components/index.d.ts +3 -0
  86. package/dist/editor.d.ts +5 -0
  87. package/dist/editor.js +21 -0
  88. package/dist/editor.js.map +1 -0
  89. package/dist/form-info.js +33 -29
  90. package/dist/form-info.js.map +1 -1
  91. package/dist/index.d.ts +5 -0
  92. package/dist/index.js +805 -773
  93. package/dist/index.js.map +1 -1
  94. package/dist/marsun-components-core.css +4 -1
  95. package/dist/node_modules/@ckeditor/ckeditor5-basic-styles/dist/index.js +301 -0
  96. package/dist/node_modules/@ckeditor/ckeditor5-basic-styles/dist/index.js.map +1 -0
  97. package/dist/node_modules/@ckeditor/ckeditor5-clipboard/dist/index.js +1256 -0
  98. package/dist/node_modules/@ckeditor/ckeditor5-clipboard/dist/index.js.map +1 -0
  99. package/dist/node_modules/@ckeditor/ckeditor5-core/dist/index.js +2107 -0
  100. package/dist/node_modules/@ckeditor/ckeditor5-core/dist/index.js.map +1 -0
  101. package/dist/node_modules/@ckeditor/ckeditor5-editor-classic/dist/index.js +259 -0
  102. package/dist/node_modules/@ckeditor/ckeditor5-editor-classic/dist/index.js.map +1 -0
  103. package/dist/node_modules/@ckeditor/ckeditor5-engine/dist/index.js +23990 -0
  104. package/dist/node_modules/@ckeditor/ckeditor5-engine/dist/index.js.map +1 -0
  105. package/dist/node_modules/@ckeditor/ckeditor5-enter/dist/index.js +249 -0
  106. package/dist/node_modules/@ckeditor/ckeditor5-enter/dist/index.js.map +1 -0
  107. package/dist/node_modules/@ckeditor/ckeditor5-essentials/dist/index.js +47 -0
  108. package/dist/node_modules/@ckeditor/ckeditor5-essentials/dist/index.js.map +1 -0
  109. package/dist/node_modules/@ckeditor/ckeditor5-font/dist/index.js +100 -0
  110. package/dist/node_modules/@ckeditor/ckeditor5-font/dist/index.js.map +1 -0
  111. package/dist/node_modules/@ckeditor/ckeditor5-icons/dist/index.js +31 -0
  112. package/dist/node_modules/@ckeditor/ckeditor5-icons/dist/index.js.map +1 -0
  113. package/dist/node_modules/@ckeditor/ckeditor5-integrations-common/dist/index.js +194 -0
  114. package/dist/node_modules/@ckeditor/ckeditor5-integrations-common/dist/index.js.map +1 -0
  115. package/dist/node_modules/@ckeditor/ckeditor5-list/dist/index.js +2042 -0
  116. package/dist/node_modules/@ckeditor/ckeditor5-list/dist/index.js.map +1 -0
  117. package/dist/node_modules/@ckeditor/ckeditor5-mention/dist/index.js +9 -0
  118. package/dist/node_modules/@ckeditor/ckeditor5-mention/dist/index.js.map +1 -0
  119. package/dist/node_modules/@ckeditor/ckeditor5-paragraph/dist/index.js +167 -0
  120. package/dist/node_modules/@ckeditor/ckeditor5-paragraph/dist/index.js.map +1 -0
  121. package/dist/node_modules/@ckeditor/ckeditor5-react/dist/index.js +471 -0
  122. package/dist/node_modules/@ckeditor/ckeditor5-react/dist/index.js.map +1 -0
  123. package/dist/node_modules/@ckeditor/ckeditor5-select-all/dist/index.js +139 -0
  124. package/dist/node_modules/@ckeditor/ckeditor5-select-all/dist/index.js.map +1 -0
  125. package/dist/node_modules/@ckeditor/ckeditor5-typing/dist/index.js +755 -0
  126. package/dist/node_modules/@ckeditor/ckeditor5-typing/dist/index.js.map +1 -0
  127. package/dist/node_modules/@ckeditor/ckeditor5-ui/dist/index.js +7838 -0
  128. package/dist/node_modules/@ckeditor/ckeditor5-ui/dist/index.js.map +1 -0
  129. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/conversions.js +422 -0
  130. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/conversions.js.map +1 -0
  131. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/index.js +33 -0
  132. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/index.js.map +1 -0
  133. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/route.js +47 -0
  134. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/route.js.map +1 -0
  135. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-name/index.js +156 -0
  136. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-name/index.js.map +1 -0
  137. package/dist/node_modules/@ckeditor/ckeditor5-undo/dist/index.js +313 -0
  138. package/dist/node_modules/@ckeditor/ckeditor5-undo/dist/index.js.map +1 -0
  139. package/dist/node_modules/@ckeditor/ckeditor5-utils/dist/index.js +2942 -0
  140. package/dist/node_modules/@ckeditor/ckeditor5-utils/dist/index.js.map +1 -0
  141. package/dist/node_modules/@ckeditor/ckeditor5-watchdog/dist/index.js +892 -0
  142. package/dist/node_modules/@ckeditor/ckeditor5-watchdog/dist/index.js.map +1 -0
  143. package/dist/node_modules/@ckeditor/ckeditor5-widget/dist/index.js +1047 -0
  144. package/dist/node_modules/@ckeditor/ckeditor5-widget/dist/index.js.map +1 -0
  145. package/dist/node_modules/color-parse/node_modules/color-name/index.js +153 -0
  146. package/dist/node_modules/color-parse/node_modules/color-name/index.js.map +1 -0
  147. package/dist/node_modules/es-toolkit/dist/_internal/globalThis.js +7 -0
  148. package/dist/node_modules/es-toolkit/dist/_internal/globalThis.js.map +1 -0
  149. package/dist/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.js +7 -0
  150. package/dist/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.js.map +1 -0
  151. package/dist/node_modules/es-toolkit/dist/_internal/isUnsafeToWriteProperty.js +7 -0
  152. package/dist/node_modules/es-toolkit/dist/_internal/isUnsafeToWriteProperty.js.map +1 -0
  153. package/dist/node_modules/es-toolkit/dist/compat/_internal/assignValue.js +9 -0
  154. package/dist/node_modules/es-toolkit/dist/compat/_internal/assignValue.js.map +1 -0
  155. package/dist/node_modules/es-toolkit/dist/compat/_internal/getSymbols.js +7 -0
  156. package/dist/node_modules/es-toolkit/dist/compat/_internal/getSymbols.js.map +1 -0
  157. package/dist/node_modules/es-toolkit/dist/compat/_internal/getTag.js +7 -0
  158. package/dist/node_modules/es-toolkit/dist/compat/_internal/getTag.js.map +1 -0
  159. package/dist/node_modules/es-toolkit/dist/compat/_internal/isDeepKey.js +16 -0
  160. package/dist/node_modules/es-toolkit/dist/compat/_internal/isDeepKey.js.map +1 -0
  161. package/dist/node_modules/es-toolkit/dist/compat/_internal/isIndex.js +15 -0
  162. package/dist/node_modules/es-toolkit/dist/compat/_internal/isIndex.js.map +1 -0
  163. package/dist/node_modules/es-toolkit/dist/compat/_internal/isKey.js +9 -0
  164. package/dist/node_modules/es-toolkit/dist/compat/_internal/isKey.js.map +1 -0
  165. package/dist/node_modules/es-toolkit/dist/compat/_internal/isPrototype.js +8 -0
  166. package/dist/node_modules/es-toolkit/dist/compat/_internal/isPrototype.js.map +1 -0
  167. package/dist/node_modules/es-toolkit/dist/compat/_internal/tags.js +30 -0
  168. package/dist/node_modules/es-toolkit/dist/compat/_internal/tags.js.map +1 -0
  169. package/dist/node_modules/es-toolkit/dist/compat/_internal/toKey.js +8 -0
  170. package/dist/node_modules/es-toolkit/dist/compat/_internal/toKey.js.map +1 -0
  171. package/dist/node_modules/es-toolkit/dist/compat/function/debounce.js +17 -0
  172. package/dist/node_modules/es-toolkit/dist/compat/function/debounce.js.map +1 -0
  173. package/dist/node_modules/es-toolkit/dist/compat/function/throttle.js +13 -0
  174. package/dist/node_modules/es-toolkit/dist/compat/function/throttle.js.map +1 -0
  175. package/dist/node_modules/es-toolkit/dist/compat/object/assignIn.js +17 -0
  176. package/dist/node_modules/es-toolkit/dist/compat/object/assignIn.js.map +1 -0
  177. package/dist/node_modules/es-toolkit/dist/compat/object/clone.js +102 -0
  178. package/dist/node_modules/es-toolkit/dist/compat/object/clone.js.map +1 -0
  179. package/dist/node_modules/es-toolkit/dist/compat/object/cloneDeep.js +8 -0
  180. package/dist/node_modules/es-toolkit/dist/compat/object/cloneDeep.js.map +1 -0
  181. package/dist/node_modules/es-toolkit/dist/compat/object/cloneDeepWith.js +33 -0
  182. package/dist/node_modules/es-toolkit/dist/compat/object/cloneDeepWith.js.map +1 -0
  183. package/dist/node_modules/es-toolkit/dist/compat/object/get.js +39 -0
  184. package/dist/node_modules/es-toolkit/dist/compat/object/get.js.map +1 -0
  185. package/dist/node_modules/es-toolkit/dist/compat/object/has.js +21 -0
  186. package/dist/node_modules/es-toolkit/dist/compat/object/has.js.map +1 -0
  187. package/dist/node_modules/es-toolkit/dist/compat/object/keysIn.js +33 -0
  188. package/dist/node_modules/es-toolkit/dist/compat/object/keysIn.js.map +1 -0
  189. package/dist/node_modules/es-toolkit/dist/compat/object/mapValues.js +10 -0
  190. package/dist/node_modules/es-toolkit/dist/compat/object/mapValues.js.map +1 -0
  191. package/dist/node_modules/es-toolkit/dist/compat/object/merge.js +9 -0
  192. package/dist/node_modules/es-toolkit/dist/compat/object/merge.js.map +1 -0
  193. package/dist/node_modules/es-toolkit/dist/compat/object/mergeWith.js +53 -0
  194. package/dist/node_modules/es-toolkit/dist/compat/object/mergeWith.js.map +1 -0
  195. package/dist/node_modules/es-toolkit/dist/compat/object/property.js +10 -0
  196. package/dist/node_modules/es-toolkit/dist/compat/object/property.js.map +1 -0
  197. package/dist/node_modules/es-toolkit/dist/compat/object/set.js +9 -0
  198. package/dist/node_modules/es-toolkit/dist/compat/object/set.js.map +1 -0
  199. package/dist/node_modules/es-toolkit/dist/compat/object/updateWith.js +31 -0
  200. package/dist/node_modules/es-toolkit/dist/compat/object/updateWith.js.map +1 -0
  201. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArguments.js +8 -0
  202. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArguments.js.map +1 -0
  203. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArray.js +7 -0
  204. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArray.js.map +1 -0
  205. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArrayLike.js +8 -0
  206. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArrayLike.js.map +1 -0
  207. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArrayLikeObject.js +9 -0
  208. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArrayLikeObject.js.map +1 -0
  209. package/dist/node_modules/es-toolkit/dist/compat/predicate/isElement.js +9 -0
  210. package/dist/node_modules/es-toolkit/dist/compat/predicate/isElement.js.map +1 -0
  211. package/dist/node_modules/es-toolkit/dist/compat/predicate/isEqualWith.js +15 -0
  212. package/dist/node_modules/es-toolkit/dist/compat/predicate/isEqualWith.js.map +1 -0
  213. package/dist/node_modules/es-toolkit/dist/compat/predicate/isFunction.js +7 -0
  214. package/dist/node_modules/es-toolkit/dist/compat/predicate/isFunction.js.map +1 -0
  215. package/dist/node_modules/es-toolkit/dist/compat/predicate/isMatch.js +9 -0
  216. package/dist/node_modules/es-toolkit/dist/compat/predicate/isMatch.js.map +1 -0
  217. package/dist/node_modules/es-toolkit/dist/compat/predicate/isMatchWith.js +81 -0
  218. package/dist/node_modules/es-toolkit/dist/compat/predicate/isMatchWith.js.map +1 -0
  219. package/dist/node_modules/es-toolkit/dist/compat/predicate/isObject.js +7 -0
  220. package/dist/node_modules/es-toolkit/dist/compat/predicate/isObject.js.map +1 -0
  221. package/dist/node_modules/es-toolkit/dist/compat/predicate/isObjectLike.js +7 -0
  222. package/dist/node_modules/es-toolkit/dist/compat/predicate/isObjectLike.js.map +1 -0
  223. package/dist/node_modules/es-toolkit/dist/compat/predicate/isPlainObject.js +16 -0
  224. package/dist/node_modules/es-toolkit/dist/compat/predicate/isPlainObject.js.map +1 -0
  225. package/dist/node_modules/es-toolkit/dist/compat/predicate/isString.js +7 -0
  226. package/dist/node_modules/es-toolkit/dist/compat/predicate/isString.js.map +1 -0
  227. package/dist/node_modules/es-toolkit/dist/compat/predicate/isSymbol.js +7 -0
  228. package/dist/node_modules/es-toolkit/dist/compat/predicate/isSymbol.js.map +1 -0
  229. package/dist/node_modules/es-toolkit/dist/compat/predicate/isTypedArray.js +8 -0
  230. package/dist/node_modules/es-toolkit/dist/compat/predicate/isTypedArray.js.map +1 -0
  231. package/dist/node_modules/es-toolkit/dist/compat/predicate/matches.js +9 -0
  232. package/dist/node_modules/es-toolkit/dist/compat/predicate/matches.js.map +1 -0
  233. package/dist/node_modules/es-toolkit/dist/compat/predicate/matchesProperty.js +23 -0
  234. package/dist/node_modules/es-toolkit/dist/compat/predicate/matchesProperty.js.map +1 -0
  235. package/dist/node_modules/es-toolkit/dist/compat/util/eq.js +7 -0
  236. package/dist/node_modules/es-toolkit/dist/compat/util/eq.js.map +1 -0
  237. package/dist/node_modules/es-toolkit/dist/compat/util/iteratee.js +19 -0
  238. package/dist/node_modules/es-toolkit/dist/compat/util/iteratee.js.map +1 -0
  239. package/dist/node_modules/es-toolkit/dist/compat/util/times.js +11 -0
  240. package/dist/node_modules/es-toolkit/dist/compat/util/times.js.map +1 -0
  241. package/dist/node_modules/es-toolkit/dist/compat/util/toFinite.js +8 -0
  242. package/dist/node_modules/es-toolkit/dist/compat/util/toFinite.js.map +1 -0
  243. package/dist/node_modules/es-toolkit/dist/compat/util/toInteger.js +9 -0
  244. package/dist/node_modules/es-toolkit/dist/compat/util/toInteger.js.map +1 -0
  245. package/dist/node_modules/es-toolkit/dist/compat/util/toNumber.js +8 -0
  246. package/dist/node_modules/es-toolkit/dist/compat/util/toNumber.js.map +1 -0
  247. package/dist/node_modules/es-toolkit/dist/compat/util/toPath.js +37 -0
  248. package/dist/node_modules/es-toolkit/dist/compat/util/toPath.js.map +1 -0
  249. package/dist/node_modules/es-toolkit/dist/compat/util/toString.js +15 -0
  250. package/dist/node_modules/es-toolkit/dist/compat/util/toString.js.map +1 -0
  251. package/dist/node_modules/es-toolkit/dist/function/after.js +11 -0
  252. package/dist/node_modules/es-toolkit/dist/function/after.js.map +1 -0
  253. package/dist/node_modules/es-toolkit/dist/function/debounce.js +30 -0
  254. package/dist/node_modules/es-toolkit/dist/function/debounce.js.map +1 -0
  255. package/dist/node_modules/es-toolkit/dist/function/identity.js +7 -0
  256. package/dist/node_modules/es-toolkit/dist/function/identity.js.map +1 -0
  257. package/dist/node_modules/es-toolkit/dist/function/noop.js +6 -0
  258. package/dist/node_modules/es-toolkit/dist/function/noop.js.map +1 -0
  259. package/dist/node_modules/es-toolkit/dist/object/clone.js +27 -0
  260. package/dist/node_modules/es-toolkit/dist/object/clone.js.map +1 -0
  261. package/dist/node_modules/es-toolkit/dist/object/cloneDeep.js +8 -0
  262. package/dist/node_modules/es-toolkit/dist/object/cloneDeep.js.map +1 -0
  263. package/dist/node_modules/es-toolkit/dist/object/cloneDeepWith.js +121 -0
  264. package/dist/node_modules/es-toolkit/dist/object/cloneDeepWith.js.map +1 -0
  265. package/dist/node_modules/es-toolkit/dist/object/mapValues.js +12 -0
  266. package/dist/node_modules/es-toolkit/dist/object/mapValues.js.map +1 -0
  267. package/dist/node_modules/es-toolkit/dist/predicate/isBuffer.js +8 -0
  268. package/dist/node_modules/es-toolkit/dist/predicate/isBuffer.js.map +1 -0
  269. package/dist/node_modules/es-toolkit/dist/predicate/isEqual.js +9 -0
  270. package/dist/node_modules/es-toolkit/dist/predicate/isEqual.js.map +1 -0
  271. package/dist/node_modules/es-toolkit/dist/predicate/isEqualWith.js +110 -0
  272. package/dist/node_modules/es-toolkit/dist/predicate/isEqualWith.js.map +1 -0
  273. package/dist/node_modules/es-toolkit/dist/predicate/isLength.js +7 -0
  274. package/dist/node_modules/es-toolkit/dist/predicate/isLength.js.map +1 -0
  275. package/dist/node_modules/es-toolkit/dist/predicate/isPlainObject.js +9 -0
  276. package/dist/node_modules/es-toolkit/dist/predicate/isPlainObject.js.map +1 -0
  277. package/dist/node_modules/es-toolkit/dist/predicate/isPrimitive.js +7 -0
  278. package/dist/node_modules/es-toolkit/dist/predicate/isPrimitive.js.map +1 -0
  279. package/dist/node_modules/es-toolkit/dist/predicate/isTypedArray.js +7 -0
  280. package/dist/node_modules/es-toolkit/dist/predicate/isTypedArray.js.map +1 -0
  281. package/dist/styles/global.css +4 -1
  282. package/dist/utils/copyText.d.ts +4 -0
  283. package/dist/utils/copyText.js +21 -0
  284. package/dist/utils/copyText.js.map +1 -0
  285. package/package.json +9 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../../node_modules/@ckeditor/ckeditor5-engine/dist/index.js"],"sourcesContent":["/**\n * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n */\nimport { CKEditorError, Collection, DomEmitterMixin, EmitterMixin, EventInfo, ObservableMixin, compareArrays, count, diff, env, fastDiff, first, getAncestors, getCode, global, indexOf, insertAt, isArrowKeyCode, isComment, isInsideCombinedSymbol, isInsideEmojiSequence, isInsideSurrogatePair, isIterable, isNode, isText, isValidAttributeName, keyCodes, logWarning, priorities, remove as remove$1, scrollViewportToShowTarget, spliceArray, toArray, toMap, uid } from \"@ckeditor/ckeditor5-utils\";\nimport { clone, cloneDeep, debounce, extend, get, isEmpty, isEqual, isEqualWith, isObject, isPlainObject, merge, set } from \"es-toolkit/compat\";\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\nconst documentPlaceholders = /* @__PURE__ */ new WeakMap();\nlet hasDisplayedPlaceholderDeprecationWarning = false;\n/**\n* A helper that enables a placeholder on the provided view element (also updates its visibility).\n* The placeholder is a CSS pseudo–element (with a text content) attached to the element.\n*\n* To change the placeholder text, change value of the `placeholder` property in the provided `element`.\n*\n* To disable the placeholder, use {@link module:engine/view/placeholder~disableViewPlaceholder `disableViewPlaceholder()`} helper.\n*\n* @param options Configuration options of the placeholder.\n* @param options.view Editing view instance.\n* @param options.element Element that will gain a placeholder. See `options.isDirectHost` to learn more.\n* @param options.isDirectHost If set `false`, the placeholder will not be enabled directly\n* in the passed `element` but in one of its children (selected automatically, i.e. a first empty child element).\n* Useful when attaching placeholders to elements that can host other elements (not just text), for instance,\n* editable root elements.\n* @param options.text Placeholder text. It's **deprecated** and will be removed soon. Use\n* {@link module:engine/view/placeholder~PlaceholderableViewElement#placeholder `options.element.placeholder`} instead.\n* @param options.keepOnFocus If set `true`, the placeholder stay visible when the host element is focused.\n*/\nfunction enableViewPlaceholder({ view, element, text, isDirectHost = true, keepOnFocus = false }) {\n\tconst doc = view.document;\n\tif (!documentPlaceholders.has(doc)) {\n\t\tdocumentPlaceholders.set(doc, /* @__PURE__ */ new Map());\n\t\tdoc.registerPostFixer((writer) => updateDocumentPlaceholders(documentPlaceholders.get(doc), writer));\n\t\tdoc.on(\"change:isComposing\", () => {\n\t\t\tview.change((writer) => updateDocumentPlaceholders(documentPlaceholders.get(doc), writer));\n\t\t}, { priority: \"high\" });\n\t}\n\tif (element.is(\"editableElement\")) element.on(\"change:placeholder\", (evtInfo, evt, text) => setPlaceholder(text));\n\tif (element.placeholder) setPlaceholder(element.placeholder);\n\telse if (text) setPlaceholder(text);\n\tif (text) showViewPlaceholderTextDeprecationWarning();\n\tfunction setPlaceholder(text) {\n\t\tconst config = {\n\t\t\ttext,\n\t\t\tisDirectHost,\n\t\t\tkeepOnFocus,\n\t\t\thostElement: isDirectHost ? element : null\n\t\t};\n\t\tdocumentPlaceholders.get(doc).set(element, config);\n\t\tview.change((writer) => updateDocumentPlaceholders([[element, config]], writer));\n\t}\n}\n/**\n* Disables the placeholder functionality from a given element.\n*\n* See {@link module:engine/view/placeholder~enableViewPlaceholder `enableViewPlaceholder()`} to learn more.\n*/\nfunction disableViewPlaceholder(view, element) {\n\tconst doc = element.document;\n\tif (!documentPlaceholders.has(doc)) return;\n\tview.change((writer) => {\n\t\tconst placeholders = documentPlaceholders.get(doc);\n\t\tconst config = placeholders.get(element);\n\t\twriter.removeAttribute(\"data-placeholder\", config.hostElement);\n\t\thideViewPlaceholder(writer, config.hostElement);\n\t\tplaceholders.delete(element);\n\t});\n}\n/**\n* Shows a placeholder in the provided element by changing related attributes and CSS classes.\n*\n* **Note**: This helper will not update the placeholder visibility nor manage the\n* it in any way in the future. What it does is a one–time state change of an element. Use\n* {@link module:engine/view/placeholder~enableViewPlaceholder `enableViewPlaceholder()`} and\n* {@link module:engine/view/placeholder~disableViewPlaceholder `disableViewPlaceholder()`} for full\n* placeholder functionality.\n*\n* **Note**: This helper will blindly show the placeholder directly in the root editable element if\n* one is passed, which could result in a visual clash if the editable element has some children\n* (for instance, an empty paragraph). Use {@link module:engine/view/placeholder~enableViewPlaceholder `enableViewPlaceholder()`}\n* in that case or make sure the correct element is passed to the helper.\n*\n* @returns `true`, if any changes were made to the `element`.\n*/\nfunction showViewPlaceholder(writer, element) {\n\tif (!element.hasClass(\"ck-placeholder\")) {\n\t\twriter.addClass(\"ck-placeholder\", element);\n\t\treturn true;\n\t}\n\treturn false;\n}\n/**\n* Hides a placeholder in the element by changing related attributes and CSS classes.\n*\n* **Note**: This helper will not update the placeholder visibility nor manage the\n* it in any way in the future. What it does is a one–time state change of an element. Use\n* {@link module:engine/view/placeholder~enableViewPlaceholder `enableViewPlaceholder()`} and\n* {@link module:engine/view/placeholder~disableViewPlaceholder `disableViewPlaceholder()`} for full\n* placeholder functionality.\n*\n* @returns `true`, if any changes were made to the `element`.\n*/\nfunction hideViewPlaceholder(writer, element) {\n\tif (element.hasClass(\"ck-placeholder\")) {\n\t\twriter.removeClass(\"ck-placeholder\", element);\n\t\treturn true;\n\t}\n\treturn false;\n}\n/**\n* Checks if a placeholder should be displayed in the element.\n*\n* **Note**: This helper will blindly check the possibility of showing a placeholder directly in the\n* root editable element if one is passed, which may not be the expected result. If an element can\n* host other elements (not just text), most likely one of its children should be checked instead\n* because it will be the final host for the placeholder. Use\n* {@link module:engine/view/placeholder~enableViewPlaceholder `enableViewPlaceholder()`} in that case or make\n* sure the correct element is passed to the helper.\n*\n* @param element Element that holds the placeholder.\n* @param keepOnFocus Focusing the element will keep the placeholder visible.\n*/\nfunction needsViewPlaceholder(element, keepOnFocus) {\n\tif (!element.isAttached()) return false;\n\tif (hasContent(element)) return false;\n\tconst doc = element.document;\n\tconst selectionAnchor = doc.selection.anchor;\n\tif (doc.isComposing && selectionAnchor && selectionAnchor.parent === element) return false;\n\tif (keepOnFocus) return true;\n\tif (!doc.isFocused) return true;\n\treturn !!selectionAnchor && selectionAnchor.parent !== element;\n}\n/**\n* Anything but uiElement(s) counts as content.\n*/\nfunction hasContent(element) {\n\tfor (const child of element.getChildren()) if (!child.is(\"uiElement\")) return true;\n\treturn false;\n}\n/**\n* Updates all placeholders associated with a document in a post–fixer callback.\n*\n* @returns True if any changes were made to the view document.\n*/\nfunction updateDocumentPlaceholders(placeholders, writer) {\n\tconst directHostElements = [];\n\tlet wasViewModified = false;\n\tfor (const [element, config] of placeholders) if (config.isDirectHost) {\n\t\tdirectHostElements.push(element);\n\t\tif (updatePlaceholder(writer, element, config)) wasViewModified = true;\n\t}\n\tfor (const [element, config] of placeholders) {\n\t\tif (config.isDirectHost) continue;\n\t\tconst hostElement = getChildPlaceholderHostSubstitute(element);\n\t\tif (hostElement !== config.hostElement && config.hostElement) {\n\t\t\twriter.removeAttribute(\"data-placeholder\", config.hostElement);\n\t\t\thideViewPlaceholder(writer, config.hostElement);\n\t\t\tconfig.hostElement = null;\n\t\t\twasViewModified = true;\n\t\t}\n\t\tif (!hostElement) continue;\n\t\tif (directHostElements.includes(hostElement)) continue;\n\t\tconfig.hostElement = hostElement;\n\t\tif (updatePlaceholder(writer, element, config)) wasViewModified = true;\n\t}\n\treturn wasViewModified;\n}\n/**\n* Updates a single placeholder in a post–fixer callback.\n*\n* @returns True if any changes were made to the view document.\n*/\nfunction updatePlaceholder(writer, element, config) {\n\tconst { text, isDirectHost, hostElement } = config;\n\tlet wasViewModified = false;\n\tif (hostElement.getAttribute(\"data-placeholder\") !== text) {\n\t\twriter.setAttribute(\"data-placeholder\", text, hostElement);\n\t\twasViewModified = true;\n\t}\n\tif ((isDirectHost || element.childCount == 1) && needsViewPlaceholder(hostElement, config.keepOnFocus)) {\n\t\tif (showViewPlaceholder(writer, hostElement)) wasViewModified = true;\n\t} else if (hideViewPlaceholder(writer, hostElement)) wasViewModified = true;\n\treturn wasViewModified;\n}\n/**\n* Gets a child element capable of displaying a placeholder if a parent element can host more\n* than just text (for instance, when it is a root editable element). The child element\n* can then be used in other placeholder helpers as a substitute of its parent.\n*/\nfunction getChildPlaceholderHostSubstitute(parent) {\n\tif (parent.childCount) {\n\t\tconst firstChild = parent.getChild(0);\n\t\tif (firstChild.is(\"element\") && !firstChild.is(\"uiElement\") && !firstChild.is(\"attributeElement\")) return firstChild;\n\t}\n\treturn null;\n}\n/**\n* Displays a deprecation warning message in the console, but only once per page load.\n*/\nfunction showViewPlaceholderTextDeprecationWarning() {\n\tif (!hasDisplayedPlaceholderDeprecationWarning)\n /**\n\t* The \"text\" option in the {@link module:engine/view/placeholder~enableViewPlaceholder `enableViewPlaceholder()`}\n\t* function is deprecated and will be removed soon.\n\t*\n\t* See the `#view-element-placeholder` section in the `Update to v39.x` section in the\n\t* {@glink updating/guides/updating-from-older-versions updating from older versions} guide\n\t* for more information on how to apply this change.\n\t*\n\t* @error enableViewPlaceholder-deprecated-text-option\n\t*/\n\tlogWarning(\"enableViewPlaceholder-deprecated-text-option\");\n\thasDisplayedPlaceholderDeprecationWarning = true;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\nvar ViewTypeCheckable = class {\n\t/* v8 ignore next -- @preserve */\n\tis() {\n\t\tthrow new Error(\"is() method is abstract\");\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/node\n*/\nconst ViewNodeBase = /* #__PURE__ */ EmitterMixin(ViewTypeCheckable);\n/**\n* Abstract view node class.\n*\n* This is an abstract class. Its constructor should not be used directly.\n* Use the {@link module:engine/view/downcastwriter~ViewDowncastWriter} or {@link module:engine/view/upcastwriter~ViewUpcastWriter}\n* to create new instances of view nodes.\n*/\nvar ViewNode = class extends ViewNodeBase {\n\t/**\n\t* The document instance to which this node belongs.\n\t*/\n\tdocument;\n\t/**\n\t* Parent element. Null by default. Set by {@link module:engine/view/element~ViewElement#_insertChild}.\n\t*/\n\tparent;\n\t/**\n\t* Creates a tree view node.\n\t*\n\t* @param document The document instance to which this node belongs.\n\t*/\n\tconstructor(document) {\n\t\tsuper();\n\t\tthis.document = document;\n\t\tthis.parent = null;\n\t}\n\t/**\n\t* Index of the node in the parent element or null if the node has no parent.\n\t*\n\t* Accessing this property throws an error if this node's parent element does not contain it.\n\t* This means that view tree got broken.\n\t*/\n\tget index() {\n\t\tlet pos;\n\t\tif (!this.parent) return null;\n\t\tif ((pos = this.parent.getChildIndex(this)) == -1)\n /**\n\t\t* The node's parent does not contain this node. It means that the document tree is corrupted.\n\t\t*\n\t\t* @error view-node-not-found-in-parent\n\t\t*/\n\t\tthrow new CKEditorError(\"view-node-not-found-in-parent\", this);\n\t\treturn pos;\n\t}\n\t/**\n\t* Node's next sibling, or `null` if it is the last child.\n\t*/\n\tget nextSibling() {\n\t\tconst index = this.index;\n\t\treturn index !== null && this.parent.getChild(index + 1) || null;\n\t}\n\t/**\n\t* Node's previous sibling, or `null` if it is the first child.\n\t*/\n\tget previousSibling() {\n\t\tconst index = this.index;\n\t\treturn index !== null && this.parent.getChild(index - 1) || null;\n\t}\n\t/**\n\t* Top-most ancestor of the node. If the node has no parent it is the root itself.\n\t*/\n\tget root() {\n\t\tlet root = this;\n\t\twhile (root.parent) root = root.parent;\n\t\treturn root;\n\t}\n\t/**\n\t* Returns true if the node is in a tree rooted in the document (is a descendant of one of its roots).\n\t*/\n\tisAttached() {\n\t\treturn this.root.is(\"rootElement\");\n\t}\n\t/**\n\t* Gets a path to the node. The path is an array containing indices of consecutive ancestors of this node,\n\t* beginning from {@link module:engine/view/node~ViewNode#root root}, down to this node's index.\n\t*\n\t* ```ts\n\t* const abc = downcastWriter.createText( 'abc' );\n\t* const foo = downcastWriter.createText( 'foo' );\n\t* const h1 = downcastWriter.createElement( 'h1', null, downcastWriter.createText( 'header' ) );\n\t* const p = downcastWriter.createElement( 'p', null, [ abc, foo ] );\n\t* const div = downcastWriter.createElement( 'div', null, [ h1, p ] );\n\t* foo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t* h1.getPath(); // Returns [ 0 ].\n\t* div.getPath(); // Returns [].\n\t* ```\n\t*\n\t* @returns The path.\n\t*/\n\tgetPath() {\n\t\tconst path = [];\n\t\tlet node = this;\n\t\twhile (node.parent) {\n\t\t\tpath.unshift(node.index);\n\t\t\tnode = node.parent;\n\t\t}\n\t\treturn path;\n\t}\n\t/**\n\t* Returns ancestors array of this node.\n\t*\n\t* @param options Options object.\n\t* @param options.includeSelf When set to `true` this node will be also included in parent's array.\n\t* @param options.parentFirst When set to `true`, array will be sorted from node's parent to root element,\n\t* otherwise root element will be the first item in the array.\n\t* @returns Array with ancestors.\n\t*/\n\tgetAncestors(options = {}) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\t\twhile (parent) {\n\t\t\tancestors[options.parentFirst ? \"push\" : \"unshift\"](parent);\n\t\t\tparent = parent.parent;\n\t\t}\n\t\treturn ancestors;\n\t}\n\t/**\n\t* Returns a {@link module:engine/view/element~ViewElement} or {@link module:engine/view/documentfragment~ViewDocumentFragment}\n\t* which is a common ancestor of both nodes.\n\t*\n\t* @param node The second node.\n\t* @param options Options object.\n\t* @param options.includeSelf When set to `true` both nodes will be considered \"ancestors\" too.\n\t* Which means that if e.g. node A is inside B, then their common ancestor will be B.\n\t*/\n\tgetCommonAncestor(node, options = {}) {\n\t\tconst ancestorsA = this.getAncestors(options);\n\t\tconst ancestorsB = node.getAncestors(options);\n\t\tlet i = 0;\n\t\twhile (ancestorsA[i] == ancestorsB[i] && ancestorsA[i]) i++;\n\t\treturn i === 0 ? null : ancestorsA[i - 1];\n\t}\n\t/**\n\t* Returns whether this node is before given node. `false` is returned if nodes are in different trees (for example,\n\t* in different {@link module:engine/view/documentfragment~ViewDocumentFragment}s).\n\t*\n\t* @param node Node to compare with.\n\t*/\n\tisBefore(node) {\n\t\tif (this == node) return false;\n\t\tif (this.root !== node.root) return false;\n\t\tconst thisPath = this.getPath();\n\t\tconst nodePath = node.getPath();\n\t\tconst result = compareArrays(thisPath, nodePath);\n\t\tswitch (result) {\n\t\t\tcase \"prefix\": return true;\n\t\t\tcase \"extension\": return false;\n\t\t\tdefault: return thisPath[result] < nodePath[result];\n\t\t}\n\t}\n\t/**\n\t* Returns whether this node is after given node. `false` is returned if nodes are in different trees (for example,\n\t* in different {@link module:engine/view/documentfragment~ViewDocumentFragment}s).\n\t*\n\t* @param node Node to compare with.\n\t*/\n\tisAfter(node) {\n\t\tif (this == node) return false;\n\t\tif (this.root !== node.root) return false;\n\t\treturn !this.isBefore(node);\n\t}\n\t/**\n\t* Removes node from parent.\n\t*\n\t* @internal\n\t*/\n\t_remove() {\n\t\tthis.parent._removeChildren(this.index);\n\t}\n\t/**\n\t* @internal\n\t* @param type Type of the change.\n\t* @param node Changed node.\n\t* @param data Additional data.\n\t* @fires change\n\t*/\n\t_fireChange(type, node, data) {\n\t\tthis.fire(`change:${type}`, node, data);\n\t\tif (this.parent) this.parent._fireChange(type, node, data);\n\t}\n\t/**\n\t* Converts `ViewNode` to plain object and returns it.\n\t*\n\t* @returns `ViewNode` converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = {\n\t\t\tpath: this.getPath(),\n\t\t\ttype: \"Node\"\n\t\t};\n\t\tif (this !== this.root && this.root.is(\"rootElement\")) json.root = this.root.toJSON();\n\t\treturn json;\n\t}\n};\nViewNode.prototype.is = function(type) {\n\treturn type === \"node\" || type === \"view:node\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/text\n*/\n/**\n* Tree view text node.\n*\n* The constructor of this class should not be used directly. To create a new text node instance\n* use the {@link module:engine/view/downcastwriter~ViewDowncastWriter#createText `ViewDowncastWriter#createText()`}\n* method when working on data downcasted from the model or the\n* {@link module:engine/view/upcastwriter~ViewUpcastWriter#createText `ViewUpcastWriter#createText()`}\n* method when working on non-semantic views.\n*/\nvar ViewText = class ViewText extends ViewNode {\n\t/**\n\t* The text content.\n\t*\n\t* Setting the data fires the {@link module:engine/view/node~ViewNode#event:change:text change event}.\n\t*/\n\t_textData;\n\t/**\n\t* Creates a tree view text node.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#createText\n\t* @internal\n\t* @param document The document instance to which this text node belongs.\n\t* @param data The text's data.\n\t*/\n\tconstructor(document, data) {\n\t\tsuper(document);\n\t\tthis._textData = data;\n\t}\n\t/**\n\t* The text content.\n\t*/\n\tget data() {\n\t\treturn this._textData;\n\t}\n\t/**\n\t* The `_data` property is controlled by a getter and a setter.\n\t*\n\t* The getter is required when using the addition assignment operator on protected property:\n\t*\n\t* ```ts\n\t* const foo = downcastWriter.createText( 'foo' );\n\t* const bar = downcastWriter.createText( 'bar' );\n\t*\n\t* foo._data += bar.data; // executes: `foo._data = foo._data + bar.data`\n\t* console.log( foo.data ); // prints: 'foobar'\n\t* ```\n\t*\n\t* If the protected getter didn't exist, `foo._data` will return `undefined` and result of the merge will be invalid.\n\t*\n\t* The setter sets data and fires the {@link module:engine/view/node~ViewNode#event:change:text change event}.\n\t*\n\t* @internal\n\t*/\n\tget _data() {\n\t\treturn this.data;\n\t}\n\tset _data(data) {\n\t\tthis._fireChange(\"text\", this);\n\t\tthis._textData = data;\n\t}\n\t/**\n\t* Checks if this text node is similar to other text node.\n\t* Both nodes should have the same data to be considered as similar.\n\t*\n\t* @param otherNode Node to check if it is same as this node.\n\t*/\n\tisSimilar(otherNode) {\n\t\tif (!(otherNode instanceof ViewText)) return false;\n\t\treturn this === otherNode || this.data === otherNode.data;\n\t}\n\t/**\n\t* Converts `ViewText` instance to plain object and returns it.\n\t*\n\t* @returns `ViewText` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.type = \"Text\";\n\t\tjson.data = this.data;\n\t\treturn json;\n\t}\n\t/**\n\t* Clones this node.\n\t*\n\t* @internal\n\t* @returns Text node that is a clone of this node.\n\t*/\n\t_clone() {\n\t\treturn new ViewText(this.document, this.data);\n\t}\n};\nViewText.prototype.is = function(type) {\n\treturn type === \"$text\" || type === \"view:$text\" || type === \"text\" || type === \"view:text\" || type === \"node\" || type === \"view:node\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/textproxy\n*/\n/**\n* ViewTextProxy is a wrapper for substring of {@link module:engine/view/text~ViewText}. Instance of this class is created by\n* {@link module:engine/view/treewalker~ViewTreeWalker} when only a part of {@link module:engine/view/text~ViewText} needs to be returned.\n*\n* `ViewTextProxy` has an API similar to {@link module:engine/view/text~ViewText Text} and allows to do most of the common tasks performed\n* on view nodes.\n*\n* **Note:** Some `ViewTextProxy` instances may represent whole text node, not just a part of it.\n* See {@link module:engine/view/textproxy~ViewTextProxy#isPartial}.\n*\n* **Note:** `ViewTextProxy` is a readonly interface.\n*\n* **Note:** `ViewTextProxy` instances are created on the fly basing\n* on the current state of parent {@link module:engine/view/text~ViewText}.\n* Because of this it is highly unrecommended to store references to `TextProxy instances because they might get\n* invalidated due to operations on Document. Also ViewTextProxy is not a {@link module:engine/view/node~ViewNode} so it cannot be\n* inserted as a child of {@link module:engine/view/element~ViewElement}.\n*\n* `ViewTextProxy` instances are created by {@link module:engine/view/treewalker~ViewTreeWalker view tree walker}.\n* You should not need to create an instance of this class by your own.\n*/\nvar ViewTextProxy = class extends ViewTypeCheckable {\n\t/**\n\t* Reference to the {@link module:engine/view/text~ViewText} element which ViewTextProxy is a substring.\n\t*/\n\ttextNode;\n\t/**\n\t* Text data represented by this text proxy.\n\t*/\n\tdata;\n\t/**\n\t* Offset in the `textNode` where this `ViewTextProxy` instance starts.\n\t*/\n\toffsetInText;\n\t/**\n\t* Creates a text proxy.\n\t*\n\t* @internal\n\t* @param textNode Text node which part is represented by this text proxy.\n\t* @param offsetInText Offset in {@link module:engine/view/textproxy~ViewTextProxy#textNode text node}\n\t* from which the text proxy starts.\n\t* @param length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t*/\n\tconstructor(textNode, offsetInText, length) {\n\t\tsuper();\n\t\tthis.textNode = textNode;\n\t\tif (offsetInText < 0 || offsetInText > textNode.data.length)\n /**\n\t\t* Given offsetInText value is incorrect.\n\t\t*\n\t\t* @error view-textproxy-wrong-offsetintext\n\t\t*/\n\t\tthrow new CKEditorError(\"view-textproxy-wrong-offsetintext\", this);\n\t\tif (length < 0 || offsetInText + length > textNode.data.length)\n /**\n\t\t* Given length value is incorrect.\n\t\t*\n\t\t* @error view-textproxy-wrong-length\n\t\t*/\n\t\tthrow new CKEditorError(\"view-textproxy-wrong-length\", this);\n\t\tthis.data = textNode.data.substring(offsetInText, offsetInText + length);\n\t\tthis.offsetInText = offsetInText;\n\t}\n\t/**\n\t* Offset size of this node.\n\t*/\n\tget offsetSize() {\n\t\treturn this.data.length;\n\t}\n\t/**\n\t* Flag indicating whether `ViewTextProxy` instance covers only part of the original {@link module:engine/view/text~ViewText text node}\n\t* (`true`) or the whole text node (`false`).\n\t*\n\t* This is `false` when text proxy starts at the very beginning of {@link module:engine/view/textproxy~ViewTextProxy#textNode textNode}\n\t* ({@link module:engine/view/textproxy~ViewTextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t* text node size.\n\t*/\n\tget isPartial() {\n\t\treturn this.data.length !== this.textNode.data.length;\n\t}\n\t/**\n\t* Parent of this text proxy, which is same as parent of text node represented by this text proxy.\n\t*/\n\tget parent() {\n\t\treturn this.textNode.parent;\n\t}\n\t/**\n\t* Root of this text proxy, which is same as root of text node represented by this text proxy.\n\t*/\n\tget root() {\n\t\treturn this.textNode.root;\n\t}\n\t/**\n\t* {@link module:engine/view/document~ViewDocument View document} that owns this text proxy, or `null` if the text proxy is inside\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment}.\n\t*/\n\tget document() {\n\t\treturn this.textNode.document;\n\t}\n\t/**\n\t* Returns ancestors array of this text proxy.\n\t*\n\t* @param options Options object.\n\t* @param options.includeSelf When set to `true`, textNode will be also included in parent's array.\n\t* @param options.parentFirst When set to `true`, array will be sorted from text proxy parent to\n\t* root element, otherwise root element will be the first item in the array.\n\t* @returns Array with ancestors.\n\t*/\n\tgetAncestors(options = {}) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this.textNode : this.parent;\n\t\twhile (parent !== null) {\n\t\t\tancestors[options.parentFirst ? \"push\" : \"unshift\"](parent);\n\t\t\tparent = parent.parent;\n\t\t}\n\t\treturn ancestors;\n\t}\n};\nViewTextProxy.prototype.is = function(type) {\n\treturn type === \"$textProxy\" || type === \"view:$textProxy\" || type === \"textProxy\" || type === \"view:textProxy\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/conversion/viewconsumable\n*/\n/**\n* Class used for handling consumption of view {@link module:engine/view/element~ViewElement elements},\n* {@link module:engine/view/text~ViewText text nodes} and\n* {@link module:engine/view/documentfragment~ViewDocumentFragment document fragments}.\n* Element's name and its parts (attributes, classes and styles) can be consumed separately. Consuming an element's name\n* does not consume its attributes, classes and styles.\n* To add items for consumption use {@link module:engine/conversion/viewconsumable~ViewConsumable#add add method}.\n* To test items use {@link module:engine/conversion/viewconsumable~ViewConsumable#test test method}.\n* To consume items use {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consume method}.\n* To revert already consumed items use {@link module:engine/conversion/viewconsumable~ViewConsumable#revert revert method}.\n*\n* ```ts\n* viewConsumable.add( element, { name: true } ); // Adds element's name as ready to be consumed.\n* viewConsumable.add( textNode ); // Adds text node for consumption.\n* viewConsumable.add( docFragment ); // Adds document fragment for consumption.\n* viewConsumable.test( element, { name: true } ); // Tests if element's name can be consumed.\n* viewConsumable.test( textNode ); // Tests if text node can be consumed.\n* viewConsumable.test( docFragment ); // Tests if document fragment can be consumed.\n* viewConsumable.consume( element, { name: true } ); // Consume element's name.\n* viewConsumable.consume( textNode ); // Consume text node.\n* viewConsumable.consume( docFragment ); // Consume document fragment.\n* viewConsumable.revert( element, { name: true } ); // Revert already consumed element's name.\n* viewConsumable.revert( textNode ); // Revert already consumed text node.\n* viewConsumable.revert( docFragment ); // Revert already consumed document fragment.\n* ```\n*/\nvar ViewConsumable = class ViewConsumable {\n\t/**\n\t* Map of consumable elements. If {@link module:engine/view/element~ViewElement element} is used as a key,\n\t* {@link module:engine/conversion/viewconsumable~ViewElementConsumables ViewElementConsumables} instance is stored as value.\n\t* For {@link module:engine/view/text~ViewText text nodes} and\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment document fragments} boolean value is stored as value.\n\t*/\n\t_consumables = /* @__PURE__ */ new Map();\n\t/**\n\t* Adds view {@link module:engine/view/element~ViewElement element}, {@link module:engine/view/text~ViewText text node} or\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment} as ready to be consumed.\n\t*\n\t* ```ts\n\t* viewConsumable.add( p, { name: true } ); // Adds element's name to consume.\n\t* viewConsumable.add( p, { attributes: 'name' } ); // Adds element's attribute.\n\t* viewConsumable.add( p, { classes: 'foobar' } ); // Adds element's class.\n\t* viewConsumable.add( p, { styles: 'color' } ); // Adds element's style\n\t* viewConsumable.add( p, { attributes: 'name', styles: 'color' } ); // Adds attribute and style.\n\t* viewConsumable.add( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be provided.\n\t* viewConsumable.add( textNode ); // Adds text node to consume.\n\t* viewConsumable.add( docFragment ); // Adds document fragment to consume.\n\t* ```\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t* attribute is provided - it should be handled separately by providing actual style/class.\n\t*\n\t* ```ts\n\t* viewConsumable.add( p, { attributes: 'style' } ); // This call will throw an exception.\n\t* viewConsumable.add( p, { styles: 'color' } ); // This is properly handled style.\n\t* ```\n\t*\n\t* @param consumables Used only if first parameter is {@link module:engine/view/element~ViewElement view element} instance.\n\t* @param consumables.name If set to true element's name will be included.\n\t* @param consumables.attributes Attribute name or array of attribute names.\n\t* @param consumables.classes Class name or array of class names.\n\t* @param consumables.styles Style name or array of style names.\n\t*/\n\tadd(element, consumables) {\n\t\tlet elementConsumables;\n\t\tif (element.is(\"$text\") || element.is(\"documentFragment\")) {\n\t\t\tthis._consumables.set(element, true);\n\t\t\treturn;\n\t\t}\n\t\tif (!this._consumables.has(element)) {\n\t\t\telementConsumables = new ViewElementConsumables(element);\n\t\t\tthis._consumables.set(element, elementConsumables);\n\t\t} else elementConsumables = this._consumables.get(element);\n\t\telementConsumables.add(consumables ? normalizeConsumables(consumables) : element._getConsumables());\n\t}\n\t/**\n\t* Tests if {@link module:engine/view/element~ViewElement view element}, {@link module:engine/view/text~ViewText text node} or\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment} can be consumed.\n\t* It returns `true` when all items included in method's call can be consumed. Returns `false` when\n\t* first already consumed item is found and `null` when first non-consumable item is found.\n\t*\n\t* ```ts\n\t* viewConsumable.test( p, { name: true } ); // Tests element's name.\n\t* viewConsumable.test( p, { attributes: 'name' } ); // Tests attribute.\n\t* viewConsumable.test( p, { classes: 'foobar' } ); // Tests class.\n\t* viewConsumable.test( p, { styles: 'color' } ); // Tests style.\n\t* viewConsumable.test( p, { attributes: 'name', styles: 'color' } ); // Tests attribute and style.\n\t* viewConsumable.test( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be tested.\n\t* viewConsumable.test( textNode ); // Tests text node.\n\t* viewConsumable.test( docFragment ); // Tests document fragment.\n\t* ```\n\t*\n\t* Testing classes and styles as attribute will test if all added classes/styles can be consumed.\n\t*\n\t* ```ts\n\t* viewConsumable.test( p, { attributes: 'class' } ); // Tests if all added classes can be consumed.\n\t* viewConsumable.test( p, { attributes: 'style' } ); // Tests if all added styles can be consumed.\n\t* ```\n\t*\n\t* @param consumables Used only if first parameter is {@link module:engine/view/element~ViewElement view element} instance.\n\t* @param consumables.name If set to true element's name will be included.\n\t* @param consumables.attributes Attribute name or array of attribute names.\n\t* @param consumables.classes Class name or array of class names.\n\t* @param consumables.styles Style name or array of style names.\n\t* @returns Returns `true` when all items included in method's call can be consumed. Returns `false`\n\t* when first already consumed item is found and `null` when first non-consumable item is found.\n\t*/\n\ttest(element, consumables) {\n\t\tconst elementConsumables = this._consumables.get(element);\n\t\tif (elementConsumables === void 0) return null;\n\t\tif (element.is(\"$text\") || element.is(\"documentFragment\")) return elementConsumables;\n\t\treturn elementConsumables.test(normalizeConsumables(consumables));\n\t}\n\t/**\n\t* Consumes {@link module:engine/view/element~ViewElement view element}, {@link module:engine/view/text~ViewText text node} or\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment}.\n\t* It returns `true` when all items included in method's call can be consumed, otherwise returns `false`.\n\t*\n\t* ```ts\n\t* viewConsumable.consume( p, { name: true } ); // Consumes element's name.\n\t* viewConsumable.consume( p, { attributes: 'name' } ); // Consumes element's attribute.\n\t* viewConsumable.consume( p, { classes: 'foobar' } ); // Consumes element's class.\n\t* viewConsumable.consume( p, { styles: 'color' } ); // Consumes element's style.\n\t* viewConsumable.consume( p, { attributes: 'name', styles: 'color' } ); // Consumes attribute and style.\n\t* viewConsumable.consume( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be consumed.\n\t* viewConsumable.consume( textNode ); // Consumes text node.\n\t* viewConsumable.consume( docFragment ); // Consumes document fragment.\n\t* ```\n\t*\n\t* Consuming classes and styles as attribute will test if all added classes/styles can be consumed.\n\t*\n\t* ```ts\n\t* viewConsumable.consume( p, { attributes: 'class' } ); // Consume only if all added classes can be consumed.\n\t* viewConsumable.consume( p, { attributes: 'style' } ); // Consume only if all added styles can be consumed.\n\t* ```\n\t*\n\t* @param consumables Used only if first parameter is {@link module:engine/view/element~ViewElement view element} instance.\n\t* @param consumables.name If set to true element's name will be included.\n\t* @param consumables.attributes Attribute name or array of attribute names.\n\t* @param consumables.classes Class name or array of class names.\n\t* @param consumables.styles Style name or array of style names.\n\t* @returns Returns `true` when all items included in method's call can be consumed,\n\t* otherwise returns `false`.\n\t*/\n\tconsume(element, consumables) {\n\t\tif (element.is(\"$text\") || element.is(\"documentFragment\")) {\n\t\t\tif (!this.test(element, consumables)) return false;\n\t\t\tthis._consumables.set(element, false);\n\t\t\treturn true;\n\t\t}\n\t\tconst elementConsumables = this._consumables.get(element);\n\t\tif (elementConsumables === void 0) return false;\n\t\treturn elementConsumables.consume(normalizeConsumables(consumables));\n\t}\n\t/**\n\t* Reverts {@link module:engine/view/element~ViewElement view element}, {@link module:engine/view/text~ViewText text node} or\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment} so they can be consumed once again.\n\t* Method does not revert items that were never previously added for consumption, even if they are included in\n\t* method's call.\n\t*\n\t* ```ts\n\t* viewConsumable.revert( p, { name: true } ); // Reverts element's name.\n\t* viewConsumable.revert( p, { attributes: 'name' } ); // Reverts element's attribute.\n\t* viewConsumable.revert( p, { classes: 'foobar' } ); // Reverts element's class.\n\t* viewConsumable.revert( p, { styles: 'color' } ); // Reverts element's style.\n\t* viewConsumable.revert( p, { attributes: 'name', styles: 'color' } ); // Reverts attribute and style.\n\t* viewConsumable.revert( p, { classes: [ 'baz', 'bar' ] } ); // Multiple names can be reverted.\n\t* viewConsumable.revert( textNode ); // Reverts text node.\n\t* viewConsumable.revert( docFragment ); // Reverts document fragment.\n\t* ```\n\t*\n\t* Reverting classes and styles as attribute will revert all classes/styles that were previously added for\n\t* consumption.\n\t*\n\t* ```ts\n\t* viewConsumable.revert( p, { attributes: 'class' } ); // Reverts all classes added for consumption.\n\t* viewConsumable.revert( p, { attributes: 'style' } ); // Reverts all styles added for consumption.\n\t* ```\n\t*\n\t* @param consumables Used only if first parameter is {@link module:engine/view/element~ViewElement view element} instance.\n\t* @param consumables.name If set to true element's name will be included.\n\t* @param consumables.attributes Attribute name or array of attribute names.\n\t* @param consumables.classes Class name or array of class names.\n\t* @param consumables.styles Style name or array of style names.\n\t*/\n\trevert(element, consumables) {\n\t\tconst elementConsumables = this._consumables.get(element);\n\t\tif (elementConsumables !== void 0) if (element.is(\"$text\") || element.is(\"documentFragment\")) this._consumables.set(element, true);\n\t\telse elementConsumables.revert(normalizeConsumables(consumables));\n\t}\n\t/**\n\t* Creates {@link module:engine/conversion/viewconsumable~ViewConsumable ViewConsumable} instance from\n\t* {@link module:engine/view/node~ViewNode node} or {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment}.\n\t* Instance will contain all elements, child nodes, attributes, styles and classes added for consumption.\n\t*\n\t* @param from View node or document fragment from which `ViewConsumable` will be created.\n\t* @param instance If provided, given `ViewConsumable` instance will be used\n\t* to add all consumables. It will be returned instead of a new instance.\n\t*/\n\tstatic createFrom(from, instance) {\n\t\tif (!instance) instance = new ViewConsumable();\n\t\tif (from.is(\"$text\")) instance.add(from);\n\t\telse if (from.is(\"element\") || from.is(\"documentFragment\")) {\n\t\t\tinstance.add(from);\n\t\t\tfor (const child of from.getChildren()) ViewConsumable.createFrom(child, instance);\n\t\t}\n\t\treturn instance;\n\t}\n};\n/**\n* This is a private helper-class for {@link module:engine/conversion/viewconsumable~ViewConsumable}.\n* It represents and manipulates consumable parts of a single {@link module:engine/view/element~ViewElement}.\n*\n* @internal\n*/\nvar ViewElementConsumables = class {\n\telement;\n\t/**\n\t* Flag indicating if name of the element can be consumed.\n\t*/\n\t_canConsumeName = null;\n\t/**\n\t* A map of element's consumables.\n\t* * For plain attributes the value is a boolean indicating whether the attribute is available to consume.\n\t* * For token based attributes (like class list and style) the value is a map of tokens to booleans\n\t* indicating whether the token is available to consume on the given attribute.\n\t*/\n\t_attributes = /* @__PURE__ */ new Map();\n\t/**\n\t* Creates ViewElementConsumables instance.\n\t*\n\t* @param from View element from which `ViewElementConsumables` is being created.\n\t*/\n\tconstructor(from) {\n\t\tthis.element = from;\n\t}\n\t/**\n\t* Adds consumable parts of the {@link module:engine/view/element~ViewElement view element}.\n\t* Element's name itself can be marked to be consumed (when element's name is consumed its attributes, classes and\n\t* styles still could be consumed):\n\t*\n\t* ```ts\n\t* consumables.add( { name: true } );\n\t* ```\n\t*\n\t* Attributes classes and styles:\n\t*\n\t* ```ts\n\t* consumables.add( { attributes: [ [ 'title' ], [ 'class', 'foo' ], [ 'style', 'color'] ] } );\n\t* consumables.add( { attributes: [ [ 'title' ], [ 'name' ], [ 'class', 'foo' ], [ 'class', 'bar' ] ] } );\n\t* ```\n\t*\n\t* Note: This method accepts only {@link module:engine/view/element~ViewNormalizedConsumables}.\n\t* You can use {@link module:engine/conversion/viewconsumable~normalizeConsumables} helper to convert from\n\t* {@link module:engine/conversion/viewconsumable~Consumables} to `ViewNormalizedConsumables`.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t* attribute is provided - it should be handled separately by providing `style` and `class` in consumables object.\n\t*\n\t* @param consumables Object describing which parts of the element can be consumed.\n\t*/\n\tadd(consumables) {\n\t\tif (consumables.name) this._canConsumeName = true;\n\t\tfor (const [name, token] of consumables.attributes) if (token) {\n\t\t\tlet attributeTokens = this._attributes.get(name);\n\t\t\tif (!attributeTokens || typeof attributeTokens == \"boolean\") {\n\t\t\t\tattributeTokens = /* @__PURE__ */ new Map();\n\t\t\t\tthis._attributes.set(name, attributeTokens);\n\t\t\t}\n\t\t\tattributeTokens.set(token, true);\n\t\t} else if (name == \"style\" || name == \"class\")\n /**\n\t\t* Class and style attributes should be handled separately in\n\t\t* {@link module:engine/conversion/viewconsumable~ViewConsumable#add `ViewConsumable#add()`}.\n\t\t*\n\t\t* What you have done is trying to use:\n\t\t*\n\t\t* ```ts\n\t\t* consumables.add( { attributes: [ 'class', 'style' ] } );\n\t\t* ```\n\t\t*\n\t\t* While each class and style should be registered separately:\n\t\t*\n\t\t* ```ts\n\t\t* consumables.add( { classes: 'some-class', styles: 'font-weight' } );\n\t\t* ```\n\t\t*\n\t\t* @error viewconsumable-invalid-attribute\n\t\t*/\n\t\tthrow new CKEditorError(\"viewconsumable-invalid-attribute\", this);\n\t\telse this._attributes.set(name, true);\n\t}\n\t/**\n\t* Tests if parts of the {@link module:engine/view/element~ViewElement view element} can be consumed.\n\t*\n\t* Element's name can be tested:\n\t*\n\t* ```ts\n\t* consumables.test( { name: true } );\n\t* ```\n\t*\n\t* Attributes classes and styles:\n\t*\n\t* ```ts\n\t* consumables.test( { attributes: [ [ 'title' ], [ 'class', 'foo' ], [ 'style', 'color' ] ] } );\n\t* consumables.test( { attributes: [ [ 'title' ], [ 'name' ], [ 'class', 'foo' ], [ 'class', 'bar' ] ] } );\n\t* ```\n\t*\n\t* @param consumables Object describing which parts of the element should be tested.\n\t* @returns `true` when all tested items can be consumed, `null` when even one of the items\n\t* was never marked for consumption and `false` when even one of the items was already consumed.\n\t*/\n\ttest(consumables) {\n\t\tif (consumables.name && !this._canConsumeName) return this._canConsumeName;\n\t\tfor (const [name, token] of consumables.attributes) {\n\t\t\tconst value = this._attributes.get(name);\n\t\t\tif (value === void 0) return null;\n\t\t\tif (value === false) return false;\n\t\t\tif (value === true) continue;\n\t\t\tif (!token) {\n\t\t\t\tfor (const tokenValue of value.values()) if (!tokenValue) return false;\n\t\t\t} else {\n\t\t\t\tconst tokenValue = value.get(token);\n\t\t\t\tif (tokenValue === void 0) return null;\n\t\t\t\tif (!tokenValue) return false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Tests if parts of the {@link module:engine/view/element~ViewElement view element} can be consumed and consumes them if available.\n\t* It returns `true` when all items included in method's call can be consumed, otherwise returns `false`.\n\t*\n\t* Element's name can be consumed:\n\t*\n\t* ```ts\n\t* consumables.consume( { name: true } );\n\t* ```\n\t*\n\t* Attributes classes and styles:\n\t*\n\t* ```ts\n\t* consumables.consume( { attributes: [ [ 'title' ], [ 'class', 'foo' ], [ 'style', 'color' ] ] } );\n\t* consumables.consume( { attributes: [ [ 'title' ], [ 'name' ], [ 'class', 'foo' ], [ 'class', 'bar' ] ] } );\n\t* ```\n\t*\n\t* @param consumables Object describing which parts of the element should be consumed.\n\t* @returns `true` when all tested items can be consumed and `false` when even one of the items could not be consumed.\n\t*/\n\tconsume(consumables) {\n\t\tif (!this.test(consumables)) return false;\n\t\tif (consumables.name) this._canConsumeName = false;\n\t\tfor (const [name, token] of consumables.attributes) {\n\t\t\tconst value = this._attributes.get(name);\n\t\t\tif (typeof value == \"boolean\") for (const [toConsume] of this.element._getConsumables(name, token).attributes) this._attributes.set(toConsume, false);\n\t\t\telse if (!token) for (const token of value.keys()) value.set(token, false);\n\t\t\telse for (const [, toConsume] of this.element._getConsumables(name, token).attributes) value.set(toConsume, false);\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Revert already consumed parts of {@link module:engine/view/element~ViewElement view Element}, so they can be consumed once again.\n\t* Element's name can be reverted:\n\t*\n\t* ```ts\n\t* consumables.revert( { name: true } );\n\t* ```\n\t*\n\t* Attributes classes and styles:\n\t*\n\t* ```ts\n\t* consumables.revert( { attributes: [ [ 'title' ], [ 'class', 'foo' ], [ 'style', 'color' ] ] } );\n\t* consumables.revert( { attributes: [ [ 'title' ], [ 'name' ], [ 'class', 'foo' ], [ 'class', 'bar' ] ] } );\n\t* ```\n\t*\n\t* @param consumables Object describing which parts of the element should be reverted.\n\t*/\n\trevert(consumables) {\n\t\tif (consumables.name) this._canConsumeName = true;\n\t\tfor (const [name, token] of consumables.attributes) {\n\t\t\tconst value = this._attributes.get(name);\n\t\t\tif (value === false) {\n\t\t\t\tthis._attributes.set(name, true);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (value === void 0 || value === true) continue;\n\t\t\tif (!token) for (const token of value.keys()) value.set(token, true);\n\t\t\telse if (value.get(token) === false) value.set(token, true);\n\t\t}\n\t}\n};\n/**\n* Normalizes a {@link module:engine/conversion/viewconsumable~Consumables} or {@link module:engine/view/matcher~Match}\n* to a {@link module:engine/view/element~ViewNormalizedConsumables}.\n*\n* @internal\n*/\nfunction normalizeConsumables(consumables) {\n\tconst attributes = [];\n\tif (\"attributes\" in consumables && consumables.attributes) normalizeConsumablePart(attributes, consumables.attributes);\n\tif (\"classes\" in consumables && consumables.classes) normalizeConsumablePart(attributes, consumables.classes, \"class\");\n\tif (\"styles\" in consumables && consumables.styles) normalizeConsumablePart(attributes, consumables.styles, \"style\");\n\treturn {\n\t\tname: consumables.name || false,\n\t\tattributes\n\t};\n}\n/**\n* Normalizes a list of consumable attributes to a common tuple format.\n*/\nfunction normalizeConsumablePart(attributes, items, prefix) {\n\tif (typeof items == \"string\") {\n\t\tattributes.push(prefix ? [prefix, items] : [items]);\n\t\treturn;\n\t}\n\tfor (const item of items) if (Array.isArray(item)) attributes.push(item);\n\telse attributes.push(prefix ? [prefix, item] : [item]);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* View matcher class.\n* Instance of this class can be used to find {@link module:engine/view/element~ViewElement elements} that match given pattern.\n*/\nvar Matcher = class {\n\t_patterns = [];\n\t/**\n\t* Creates new instance of Matcher.\n\t*\n\t* @param pattern Match patterns. See {@link module:engine/view/matcher~Matcher#add add method} for more information.\n\t*/\n\tconstructor(...pattern) {\n\t\tthis.add(...pattern);\n\t}\n\t/**\n\t* Adds pattern or patterns to matcher instance.\n\t*\n\t* ```ts\n\t* // String.\n\t* matcher.add( 'div' );\n\t*\n\t* // Regular expression.\n\t* matcher.add( /^\\w/ );\n\t*\n\t* // Single class.\n\t* matcher.add( {\n\t* \tclasses: 'foobar'\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/view/matcher~MatcherPattern} for more examples.\n\t*\n\t* Multiple patterns can be added in one call:\n\t*\n\t* ```ts\n\t* matcher.add( 'div', { classes: 'foobar' } );\n\t* ```\n\t*\n\t* @param pattern Object describing pattern details. If string or regular expression\n\t* is provided it will be used to match element's name. Pattern can be also provided in a form\n\t* of a function - then this function will be called with each {@link module:engine/view/element~ViewElement element} as a parameter.\n\t* Function's return value will be stored under `match` key of the object returned from\n\t* {@link module:engine/view/matcher~Matcher#match match} or {@link module:engine/view/matcher~Matcher#matchAll matchAll} methods.\n\t*/\n\tadd(...pattern) {\n\t\tfor (let item of pattern) {\n\t\t\tif (typeof item == \"string\" || item instanceof RegExp) item = { name: item };\n\t\t\tthis._patterns.push(item);\n\t\t}\n\t}\n\t/**\n\t* Matches elements for currently stored patterns. Returns match information about first found\n\t* {@link module:engine/view/element~ViewElement element}, otherwise returns `null`.\n\t*\n\t* Example of returned object:\n\t*\n\t* ```ts\n\t* {\n\t* \telement: <instance of found element>,\n\t* \tpattern: <pattern used to match found element>,\n\t* \tmatch: {\n\t* \t\tname: true,\n\t* \t\tattributes: [\n\t* \t\t\t[ 'title' ],\n\t* \t\t\t[ 'href' ],\n\t* \t\t\t[ 'class', 'foo' ],\n\t* \t\t\t[ 'style', 'color' ],\n\t* \t\t\t[ 'style', 'position' ]\n\t* \t\t]\n\t* \t}\n\t* }\n\t* ```\n\t*\n\t* You could use the `match` field from the above returned object as an input for the\n\t* {@link module:engine/conversion/viewconsumable~ViewConsumable#test `ViewConsumable#test()`} and\n\t* {@link module:engine/conversion/viewconsumable~ViewConsumable#consume `ViewConsumable#consume()`} methods.\n\t*\n\t* @see module:engine/view/matcher~Matcher#add\n\t* @see module:engine/view/matcher~Matcher#matchAll\n\t* @param element View element to match against stored patterns.\n\t* @returns The match information about found element or `null`.\n\t*/\n\tmatch(...element) {\n\t\tfor (const singleElement of element) for (const pattern of this._patterns) {\n\t\t\tconst match = this._isElementMatching(singleElement, pattern);\n\t\t\tif (match) return {\n\t\t\t\telement: singleElement,\n\t\t\t\tpattern,\n\t\t\t\tmatch\n\t\t\t};\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Matches elements for currently stored patterns. Returns array of match information with all found\n\t* {@link module:engine/view/element~ViewElement elements}. If no element is found - returns `null`.\n\t*\n\t* @see module:engine/view/matcher~Matcher#add\n\t* @see module:engine/view/matcher~Matcher#match\n\t* @param element View element to match against stored patterns.\n\t* @returns Array with match information about found elements or `null`. For more information\n\t* see {@link module:engine/view/matcher~Matcher#match match method} description.\n\t*/\n\tmatchAll(...element) {\n\t\tconst results = [];\n\t\tfor (const singleElement of element) for (const pattern of this._patterns) {\n\t\t\tconst match = this._isElementMatching(singleElement, pattern);\n\t\t\tif (match) results.push({\n\t\t\t\telement: singleElement,\n\t\t\t\tpattern,\n\t\t\t\tmatch\n\t\t\t});\n\t\t}\n\t\treturn results.length > 0 ? results : null;\n\t}\n\t/**\n\t* Returns the name of the element to match if there is exactly one pattern added to the matcher instance\n\t* and it matches element name defined by `string` (not `RegExp`). Otherwise, returns `null`.\n\t*\n\t* @returns Element name trying to match.\n\t*/\n\tgetElementName() {\n\t\tif (this._patterns.length !== 1) return null;\n\t\tconst pattern = this._patterns[0];\n\t\tconst name = pattern.name;\n\t\treturn typeof pattern != \"function\" && name && !(name instanceof RegExp) ? name : null;\n\t}\n\t/**\n\t* Returns match information if {@link module:engine/view/element~ViewElement element} is matching provided pattern.\n\t* If element cannot be matched to provided pattern - returns `null`.\n\t*\n\t* @returns Returns object with match information or null if element is not matching.\n\t*/\n\t_isElementMatching(element, pattern) {\n\t\tif (typeof pattern == \"function\") {\n\t\t\tconst match = pattern(element);\n\t\t\tif (!match || typeof match != \"object\") return match;\n\t\t\treturn normalizeConsumables(match);\n\t\t}\n\t\tconst match = {};\n\t\tif (pattern.name) {\n\t\t\tmatch.name = matchName(pattern.name, element.name);\n\t\t\tif (!match.name) return null;\n\t\t}\n\t\tconst attributesMatch = [];\n\t\tif (pattern.attributes && !matchAttributes(pattern.attributes, element, attributesMatch)) return null;\n\t\tif (pattern.classes && !matchClasses(pattern.classes, element, attributesMatch)) return null;\n\t\tif (pattern.styles && !matchStyles(pattern.styles, element, attributesMatch)) return null;\n\t\tif (attributesMatch.length) match.attributes = attributesMatch;\n\t\treturn match;\n\t}\n};\n/**\n* Returns true if the given `item` matches the pattern.\n*\n* @internal\n* @param pattern A pattern representing a key/value we want to match.\n* @param item An actual item key/value (e.g. `'src'`, `'background-color'`, `'ck-widget'`) we're testing against pattern.\n*/\nfunction isPatternMatched(pattern, item) {\n\treturn pattern === true || pattern === item || pattern instanceof RegExp && !!String(item).match(pattern);\n}\n/**\n* Checks if name can be matched by provided pattern.\n*\n* @returns Returns `true` if name can be matched, `false` otherwise.\n*/\nfunction matchName(pattern, name) {\n\tif (pattern instanceof RegExp) return !!name.match(pattern);\n\treturn pattern === name;\n}\n/**\n* Bring all the possible pattern forms to an array of tuples where first item is a key, second is a value,\n* and third optional is a token value.\n*\n* Examples:\n*\n* Boolean pattern value:\n*\n* ```ts\n* true\n* ```\n*\n* to\n*\n* ```ts\n* [ [ true, true ] ]\n* ```\n*\n* Textual pattern value:\n*\n* ```ts\n* 'attribute-name-or-class-or-style'\n* ```\n*\n* to\n*\n* ```ts\n* [ [ 'attribute-name-or-class-or-style', true ] ]\n* ```\n*\n* Regular expression:\n*\n* ```ts\n* /^data-.*$/\n* ```\n*\n* to\n*\n* ```ts\n* [ [ /^data-.*$/, true ] ]\n* ```\n*\n* Objects (plain or with `key` and `value` specified explicitly):\n*\n* ```ts\n* {\n* \tsrc: /^https:.*$/\n* }\n* ```\n*\n* or\n*\n* ```ts\n* [ {\n* \tkey: 'src',\n* \tvalue: /^https:.*$/\n* } ]\n* ```\n*\n* to:\n*\n* ```ts\n* [ [ 'src', /^https:.*$/ ] ]\n* ```\n*\n* @returns Returns an array of objects or null if provided patterns were not in an expected form.\n*/\nfunction normalizePatterns(patterns, prefix) {\n\tif (Array.isArray(patterns)) return patterns.map((pattern) => {\n\t\tif (typeof pattern !== \"object\" || pattern instanceof RegExp) return prefix ? [\n\t\t\tprefix,\n\t\t\tpattern,\n\t\t\ttrue\n\t\t] : [pattern, true];\n\t\tif (pattern.key === void 0 || pattern.value === void 0) logWarning(\"matcher-pattern-missing-key-or-value\", pattern);\n\t\treturn prefix ? [\n\t\t\tprefix,\n\t\t\tpattern.key,\n\t\t\tpattern.value\n\t\t] : [pattern.key, pattern.value];\n\t});\n\tif (typeof patterns !== \"object\" || patterns instanceof RegExp) return [prefix ? [\n\t\tprefix,\n\t\tpatterns,\n\t\ttrue\n\t] : [patterns, true]];\n\tconst normalizedPatterns = [];\n\tfor (const key in patterns) if (Object.prototype.hasOwnProperty.call(patterns, key)) normalizedPatterns.push(prefix ? [\n\t\tprefix,\n\t\tkey,\n\t\tpatterns[key]\n\t] : [key, patterns[key]]);\n\treturn normalizedPatterns;\n}\n/**\n* Checks if attributes of provided element can be matched against provided patterns.\n*\n* @param patterns Object with information about attributes to match. Each key of the object will be\n* used as attribute name. Value of each key can be a string or regular expression to match against attribute value.\n* @param element Element which attributes will be tested.\n* @param match An array to populate with matching tuples.\n* @returns Returns array with matched attribute names or `null` if no attributes were matched.\n*/\nfunction matchAttributes(patterns, element, match) {\n\tlet excludeAttributes;\n\tif (typeof patterns === \"object\" && !(patterns instanceof RegExp) && !Array.isArray(patterns)) {\n\t\tif (patterns.style !== void 0) logWarning(\"matcher-pattern-deprecated-attributes-style-key\", patterns);\n\t\tif (patterns.class !== void 0) logWarning(\"matcher-pattern-deprecated-attributes-class-key\", patterns);\n\t} else excludeAttributes = [\"class\", \"style\"];\n\treturn element._collectAttributesMatch(normalizePatterns(patterns), match, excludeAttributes);\n}\n/**\n* Checks if classes of provided element can be matched against provided patterns.\n*\n* @param patterns Array of strings or regular expressions to match against element's classes.\n* @param element Element which classes will be tested.\n* @param match An array to populate with matching tuples.\n* @returns Returns array with matched class names or `null` if no classes were matched.\n*/\nfunction matchClasses(patterns, element, match) {\n\treturn element._collectAttributesMatch(normalizePatterns(patterns, \"class\"), match);\n}\n/**\n* Checks if styles of provided element can be matched against provided patterns.\n*\n* @param patterns Object with information about styles to match. Each key of the object will be\n* used as style name. Value of each key can be a string or regular expression to match against style value.\n* @param element Element which styles will be tested.\n* @param match An array to populate with matching tuples.\n* @returns Returns array with matched style names or `null` if no styles were matched.\n*/\nfunction matchStyles(patterns, element, match) {\n\treturn element._collectAttributesMatch(normalizePatterns(patterns, \"style\"), match);\n}\n/**\n* The key-value matcher pattern is missing key or value. Both must be present.\n* Refer the documentation: {@link module:engine/view/matcher~MatcherPattern}.\n*\n* @param pattern Pattern with missing properties.\n* @error matcher-pattern-missing-key-or-value\n*/\n/**\n* The key-value matcher pattern for `attributes` option is using deprecated `style` key.\n*\n* Use `styles` matcher pattern option instead:\n*\n* ```ts\n* // Instead of:\n* const pattern = {\n* \tattributes: {\n* \t\tkey1: 'value1',\n* \t\tkey2: 'value2',\n* \t\tstyle: /^border.*$/\n* \t}\n* }\n*\n* // Use:\n* const pattern = {\n* \tattributes: {\n* \t\tkey1: 'value1',\n* \t\tkey2: 'value2'\n* \t},\n* \tstyles: /^border.*$/\n* }\n* ```\n*\n* Refer to the `#update-to-ckeditor-5-v2910` section in the `Update to v29.x` section in the\n* {@glink updating/guides/updating-from-older-versions updating from older versions} guide\n* and {@link module:engine/view/matcher~MatcherPattern} documentation.\n*\n* @param pattern Pattern with missing properties.\n* @error matcher-pattern-deprecated-attributes-style-key\n*/\n/**\n* The key-value matcher pattern for `attributes` option is using deprecated `class` key.\n*\n* Use `classes` matcher pattern option instead:\n*\n* ```ts\n* // Instead of:\n* const pattern = {\n* \tattributes: {\n* \t\tkey1: 'value1',\n* \t\tkey2: 'value2',\n* \t\tclass: 'foobar'\n* \t}\n* }\n*\n* // Use:\n* const pattern = {\n* \tattributes: {\n* \t\tkey1: 'value1',\n* \t\tkey2: 'value2'\n* \t},\n* \tclasses: 'foobar'\n* }\n* ```\n*\n* Refer to the `#update-to-ckeditor-5-v2910` paragraph in the Update to v29.x guide in the\n* {@glink updating/guides/updating-from-older-versions updating from older versions} guide\n* and the {@link module:engine/view/matcher~MatcherPattern} documentation.\n*\n* @param pattern Pattern with missing properties.\n* @error matcher-pattern-deprecated-attributes-class-key\n*/\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/stylesmap\n*/\n/**\n* Styles map. Allows handling (adding, removing, retrieving) a set of style rules (usually, of an element).\n*/\nvar StylesMap = class {\n\t/**\n\t* Keeps an internal representation of styles map. Normalized styles are kept as object tree to allow unified modification and\n\t* value access model using lodash's get, set, unset, etc methods.\n\t*\n\t* When no style processor rules are defined it acts as simple key-value storage.\n\t*/\n\t_styles;\n\t/**\n\t* Cached list of style names for faster access.\n\t*/\n\t_cachedStyleNames = null;\n\t/**\n\t* Cached list of expanded style names for faster access.\n\t*/\n\t_cachedExpandedStyleNames = null;\n\t/**\n\t* An instance of the {@link module:engine/view/stylesmap~StylesProcessor}.\n\t*/\n\t_styleProcessor;\n\t/**\n\t* Creates Styles instance.\n\t*/\n\tconstructor(styleProcessor) {\n\t\tthis._styles = {};\n\t\tthis._styleProcessor = styleProcessor;\n\t}\n\t/**\n\t* Returns true if style map has no styles set.\n\t*/\n\tget isEmpty() {\n\t\treturn !Object.entries(this._styles).length;\n\t}\n\t/**\n\t* Number of styles defined.\n\t*/\n\tget size() {\n\t\tif (this.isEmpty) return 0;\n\t\treturn this.getStyleNames().length;\n\t}\n\t/**\n\t* Set styles map to a new value.\n\t*\n\t* ```ts\n\t* styles.setTo( 'border:1px solid blue;margin-top:1px;' );\n\t* ```\n\t*/\n\tsetTo(inlineStyle) {\n\t\tthis.clear();\n\t\tconst parsedStyles = parseInlineStyles(inlineStyle);\n\t\tfor (const [key, value] of parsedStyles) this._styleProcessor.toNormalizedForm(key, value, this._styles);\n\t\treturn this;\n\t}\n\t/**\n\t* Checks if a given style is set.\n\t*\n\t* ```ts\n\t* styles.setTo( 'margin-left:1px;' );\n\t*\n\t* styles.has( 'margin-left' ); // -> true\n\t* styles.has( 'padding' ); // -> false\n\t* ```\n\t*\n\t* **Note**: This check supports normalized style names.\n\t*\n\t* ```ts\n\t* // Enable 'margin' shorthand processing:\n\t* editor.data.addStyleProcessorRules( addMarginStylesRules );\n\t*\n\t* styles.setTo( 'margin:2px;' );\n\t*\n\t* styles.has( 'margin' ); // -> true\n\t* styles.has( 'margin-top' ); // -> true\n\t* styles.has( 'margin-left' ); // -> true\n\t*\n\t* styles.remove( 'margin-top' );\n\t*\n\t* styles.has( 'margin' ); // -> false\n\t* styles.has( 'margin-top' ); // -> false\n\t* styles.has( 'margin-left' ); // -> true\n\t* ```\n\t*\n\t* @param name Style name.\n\t*/\n\thas(name) {\n\t\tif (this.isEmpty) return false;\n\t\tconst propertyDescriptor = this._styleProcessor.getReducedForm(name, this._styles).find(([property]) => property === name);\n\t\treturn Array.isArray(propertyDescriptor);\n\t}\n\tset(nameOrObject, valueOrObject) {\n\t\tthis._cachedStyleNames = null;\n\t\tthis._cachedExpandedStyleNames = null;\n\t\tif (isObject(nameOrObject)) for (const [key, value] of Object.entries(nameOrObject)) this._styleProcessor.toNormalizedForm(key, value, this._styles);\n\t\telse this._styleProcessor.toNormalizedForm(nameOrObject, valueOrObject, this._styles);\n\t}\n\t/**\n\t* Removes given style.\n\t*\n\t* ```ts\n\t* styles.setTo( 'background:#f00;margin-right:2px;' );\n\t*\n\t* styles.remove( 'background' );\n\t*\n\t* styles.toString(); // -> 'margin-right:2px;'\n\t* ```\n\t*\n\t* ***Note**:* This method uses {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules\n\t* enabled style processor rules} to normalize passed values.\n\t*\n\t* ```ts\n\t* // Enable 'margin' shorthand processing:\n\t* editor.data.addStyleProcessorRules( addMarginStylesRules );\n\t*\n\t* styles.setTo( 'margin:1px' );\n\t*\n\t* styles.remove( 'margin-top' );\n\t* styles.remove( 'margin-right' );\n\t*\n\t* styles.toString(); // -> 'margin-bottom:1px;margin-left:1px;'\n\t* ```\n\t*\n\t* @param names Style name or an array of names.\n\t*/\n\tremove(names) {\n\t\tconst normalizedStylesToRemove = {};\n\t\tfor (const name of toArray(names)) {\n\t\t\tconst path = toPath(name);\n\t\t\tconst pathValue = get(this._styles, path);\n\t\t\tif (pathValue) appendStyleValue(normalizedStylesToRemove, path, pathValue);\n\t\t\telse {\n\t\t\t\tconst value = this.getAsString(name);\n\t\t\t\tif (value !== void 0) this._styleProcessor.toNormalizedForm(name, value, normalizedStylesToRemove);\n\t\t\t}\n\t\t}\n\t\tif (Object.keys(normalizedStylesToRemove).length) {\n\t\t\tremoveStyles(this._styles, normalizedStylesToRemove);\n\t\t\tthis._cachedStyleNames = null;\n\t\t\tthis._cachedExpandedStyleNames = null;\n\t\t}\n\t}\n\t/**\n\t* Returns a normalized style object or a single value.\n\t*\n\t* ```ts\n\t* // Enable 'margin' shorthand processing:\n\t* editor.data.addStyleProcessorRules( addMarginStylesRules );\n\t*\n\t* const styles = new Styles();\n\t* styles.setTo( 'margin:1px 2px 3em;' );\n\t*\n\t* styles.getNormalized( 'margin' );\n\t* // will log:\n\t* // {\n\t* // top: '1px',\n\t* // right: '2px',\n\t* // bottom: '3em',\n\t* // left: '2px' // normalized value from margin shorthand\n\t* // }\n\t*\n\t* styles.getNormalized( 'margin-left' ); // -> '2px'\n\t* ```\n\t*\n\t* **Note**: This method will only return normalized styles if a style processor was defined.\n\t*\n\t* @param name Style name.\n\t*/\n\tgetNormalized(name) {\n\t\treturn this._styleProcessor.getNormalized(name, this._styles);\n\t}\n\t/**\n\t* Returns a normalized style string. Styles are sorted by name.\n\t*\n\t* ```ts\n\t* styles.set( 'margin' , '1px' );\n\t* styles.set( 'background', '#f00' );\n\t*\n\t* styles.toString(); // -> 'background:#f00;margin:1px;'\n\t* ```\n\t*\n\t* **Note**: This method supports normalized styles if defined.\n\t*\n\t* ```ts\n\t* // Enable 'margin' shorthand processing:\n\t* editor.data.addStyleProcessorRules( addMarginStylesRules );\n\t*\n\t* styles.set( 'margin' , '1px' );\n\t* styles.set( 'background', '#f00' );\n\t* styles.remove( 'margin-top' );\n\t* styles.remove( 'margin-right' );\n\t*\n\t* styles.toString(); // -> 'background:#f00;margin-bottom:1px;margin-left:1px;'\n\t* ```\n\t*/\n\ttoString() {\n\t\tif (this.isEmpty) return \"\";\n\t\treturn this.getStylesEntries().map((arr) => arr.join(\":\")).sort().join(\";\") + \";\";\n\t}\n\t/**\n\t* Returns property as a value string or undefined if property is not set.\n\t*\n\t* ```ts\n\t* // Enable 'margin' shorthand processing:\n\t* editor.data.addStyleProcessorRules( addMarginStylesRules );\n\t*\n\t* const styles = new Styles();\n\t* styles.setTo( 'margin:1px;' );\n\t* styles.set( 'margin-bottom', '3em' );\n\t*\n\t* styles.getAsString( 'margin' ); // -> 'margin: 1px 1px 3em;'\n\t* ```\n\t*\n\t* Note, however, that all sub-values must be set for the longhand property name to return a value:\n\t*\n\t* ```ts\n\t* const styles = new Styles();\n\t* styles.setTo( 'margin:1px;' );\n\t* styles.remove( 'margin-bottom' );\n\t*\n\t* styles.getAsString( 'margin' ); // -> undefined\n\t* ```\n\t*\n\t* In the above scenario, it is not possible to return a `margin` value, so `undefined` is returned.\n\t* Instead, you should use:\n\t*\n\t* ```ts\n\t* const styles = new Styles();\n\t* styles.setTo( 'margin:1px;' );\n\t* styles.remove( 'margin-bottom' );\n\t*\n\t* for ( const styleName of styles.getStyleNames() ) {\n\t* \tconsole.log( styleName, styles.getAsString( styleName ) );\n\t* }\n\t* // 'margin-top', '1px'\n\t* // 'margin-right', '1px'\n\t* // 'margin-left', '1px'\n\t* ```\n\t*\n\t* In general, it is recommend to iterate over style names like in the example above. This way, you will always get all\n\t* the currently set style values. So, if all the 4 margin values would be set\n\t* the for-of loop above would yield only `'margin'`, `'1px'`:\n\t*\n\t* ```ts\n\t* const styles = new Styles();\n\t* styles.setTo( 'margin:1px;' );\n\t*\n\t* for ( const styleName of styles.getStyleNames() ) {\n\t* \tconsole.log( styleName, styles.getAsString( styleName ) );\n\t* }\n\t* // 'margin', '1px'\n\t* ```\n\t*\n\t* **Note**: To get a normalized version of a longhand property use the {@link #getNormalized `#getNormalized()`} method.\n\t*/\n\tgetAsString(propertyName) {\n\t\tif (this.isEmpty) return;\n\t\tif (this._styles[propertyName] && !isObject(this._styles[propertyName])) return this._styles[propertyName];\n\t\tconst propertyDescriptor = this._styleProcessor.getReducedForm(propertyName, this._styles).find(([property]) => property === propertyName);\n\t\tif (Array.isArray(propertyDescriptor)) return propertyDescriptor[1];\n\t}\n\t/**\n\t* Returns all style properties names as they would appear when using {@link #toString `#toString()`}.\n\t*\n\t* When `expand` is set to true and there's a shorthand style property set, it will also return all equivalent styles:\n\t*\n\t* ```ts\n\t* stylesMap.setTo( 'margin: 1em' )\n\t* ```\n\t*\n\t* will be expanded to:\n\t*\n\t* ```ts\n\t* [ 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ]\n\t* ```\n\t*\n\t* @param expand Expand shorthand style properties and all return equivalent style representations.\n\t*/\n\tgetStyleNames(expand = false) {\n\t\tif (this.isEmpty) return [];\n\t\tif (expand) {\n\t\t\tthis._cachedExpandedStyleNames ||= this._styleProcessor.getStyleNames(this._styles);\n\t\t\treturn this._cachedExpandedStyleNames;\n\t\t}\n\t\tthis._cachedStyleNames ||= this.getStylesEntries().map(([key]) => key);\n\t\treturn this._cachedStyleNames;\n\t}\n\t/**\n\t* Alias for {@link #getStyleNames}.\n\t*/\n\tkeys() {\n\t\treturn this.getStyleNames();\n\t}\n\t/**\n\t* Removes all styles.\n\t*/\n\tclear() {\n\t\tthis._styles = {};\n\t\tthis._cachedStyleNames = null;\n\t\tthis._cachedExpandedStyleNames = null;\n\t}\n\t/**\n\t* Returns `true` if both attributes have the same styles.\n\t*/\n\tisSimilar(other) {\n\t\tif (this.size !== other.size) return false;\n\t\tfor (const property of this.getStyleNames()) if (!other.has(property) || other.getAsString(property) !== this.getAsString(property)) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Returns normalized styles entries for further processing.\n\t*/\n\tgetStylesEntries() {\n\t\tconst parsed = [];\n\t\tconst keys = Object.keys(this._styles);\n\t\tfor (const key of keys) parsed.push(...this._styleProcessor.getReducedForm(key, this._styles));\n\t\treturn parsed;\n\t}\n\t/**\n\t* Clones the attribute value.\n\t*\n\t* @internal\n\t*/\n\t_clone() {\n\t\tconst clone = new this.constructor(this._styleProcessor);\n\t\tclone.set(this.getNormalized());\n\t\treturn clone;\n\t}\n\t/**\n\t* Used by the {@link module:engine/view/matcher~Matcher Matcher} to collect matching styles.\n\t*\n\t* @internal\n\t* @param tokenPattern The matched style name pattern.\n\t* @param valuePattern The matched style value pattern.\n\t* @returns An array of matching tokens (style names).\n\t*/\n\t_getTokensMatch(tokenPattern, valuePattern) {\n\t\tconst match = [];\n\t\tfor (const styleName of this.getStyleNames(true)) if (isPatternMatched(tokenPattern, styleName)) {\n\t\t\tif (valuePattern === true) {\n\t\t\t\tmatch.push(styleName);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst value = this.getAsString(styleName);\n\t\t\tif (isPatternMatched(valuePattern, value)) match.push(styleName);\n\t\t}\n\t\treturn match.length ? match : void 0;\n\t}\n\t/**\n\t* Returns a list of consumables for the attribute. This includes related styles.\n\t*\n\t* Could be filtered by the given style name.\n\t*\n\t* @internal\n\t*/\n\t_getConsumables(name) {\n\t\tconst result = [];\n\t\tif (name) {\n\t\t\tresult.push(name);\n\t\t\tfor (const relatedName of this._styleProcessor.getRelatedStyles(name)) result.push(relatedName);\n\t\t} else for (const name of this.getStyleNames()) {\n\t\t\tfor (const relatedName of this._styleProcessor.getRelatedStyles(name)) result.push(relatedName);\n\t\t\tresult.push(name);\n\t\t}\n\t\treturn result;\n\t}\n\t/**\n\t* Used by {@link module:engine/view/element~ViewElement#_canMergeAttributesFrom} to verify if the given attribute can be merged without\n\t* conflicts into the attribute.\n\t*\n\t* This method is indirectly used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to merge it with other ViewAttributeElement.\n\t*\n\t* @internal\n\t*/\n\t_canMergeFrom(other) {\n\t\tfor (const key of other.getStyleNames()) if (this.has(key) && this.getAsString(key) !== other.getAsString(key)) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Used by {@link module:engine/view/element~ViewElement#_mergeAttributesFrom} to merge a given attribute into the attribute.\n\t*\n\t* This method is indirectly used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to merge it with other ViewAttributeElement.\n\t*\n\t* @internal\n\t*/\n\t_mergeFrom(other) {\n\t\tfor (const prop of other.getStyleNames()) if (!this.has(prop)) this.set(prop, other.getAsString(prop));\n\t}\n\t/**\n\t* Used by {@link module:engine/view/element~ViewElement#_canSubtractAttributesOf} to verify if the given attribute can be fully\n\t* subtracted from the attribute.\n\t*\n\t* This method is indirectly used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to unwrap the ViewAttributeElement.\n\t*\n\t* @internal\n\t*/\n\t_isMatching(other) {\n\t\tfor (const key of other.getStyleNames()) if (!this.has(key) || this.getAsString(key) !== other.getAsString(key)) return false;\n\t\treturn true;\n\t}\n};\n/**\n* Style processor is responsible for writing and reading a normalized styles object.\n*/\nvar StylesProcessor = class {\n\t_normalizers;\n\t_extractors;\n\t_reducers;\n\t_consumables;\n\t/**\n\t* Creates StylesProcessor instance.\n\t*\n\t* @internal\n\t*/\n\tconstructor() {\n\t\tthis._normalizers = /* @__PURE__ */ new Map();\n\t\tthis._extractors = /* @__PURE__ */ new Map();\n\t\tthis._reducers = /* @__PURE__ */ new Map();\n\t\tthis._consumables = /* @__PURE__ */ new Map();\n\t}\n\t/**\n\t* Parse style string value to a normalized object and appends it to styles object.\n\t*\n\t* ```ts\n\t* const styles = {};\n\t*\n\t* stylesProcessor.toNormalizedForm( 'margin', '1px', styles );\n\t*\n\t* // styles will consist: { margin: { top: '1px', right: '1px', bottom: '1px', left: '1px; } }\n\t* ```\n\t*\n\t* **Note**: To define normalizer callbacks use {@link #setNormalizer}.\n\t*\n\t* @param name Name of style property.\n\t* @param propertyValue Value of style property.\n\t* @param styles Object holding normalized styles.\n\t*/\n\ttoNormalizedForm(name, propertyValue, styles) {\n\t\tif (isObject(propertyValue)) {\n\t\t\tappendStyleValue(styles, toPath(name), propertyValue);\n\t\t\treturn;\n\t\t}\n\t\tif (this._normalizers.has(name)) {\n\t\t\tconst { path, value } = this._normalizers.get(name)(propertyValue);\n\t\t\tappendStyleValue(styles, path, value);\n\t\t} else appendStyleValue(styles, name, propertyValue);\n\t}\n\t/**\n\t* Returns a normalized version of a style property.\n\t*\n\t* ```ts\n\t* const styles = {\n\t* \tmargin: { top: '1px', right: '1px', bottom: '1px', left: '1px; },\n\t* \tbackground: { color: '#f00' }\n\t* };\n\t*\n\t* stylesProcessor.getNormalized( 'background' );\n\t* // will return: { color: '#f00' }\n\t*\n\t* stylesProcessor.getNormalized( 'margin-top' );\n\t* // will return: '1px'\n\t* ```\n\t*\n\t* **Note**: In some cases extracting single value requires defining an extractor callback {@link #setExtractor}.\n\t*\n\t* @param name Name of style property.\n\t* @param styles Object holding normalized styles.\n\t*/\n\tgetNormalized(name, styles) {\n\t\tif (!name) return merge({}, styles);\n\t\tif (styles[name] !== void 0) return styles[name];\n\t\tif (this._extractors.has(name)) {\n\t\t\tconst extractor = this._extractors.get(name);\n\t\t\tif (typeof extractor === \"string\") return get(styles, extractor);\n\t\t\tconst value = extractor(name, styles);\n\t\t\tif (value) return value;\n\t\t}\n\t\treturn get(styles, toPath(name));\n\t}\n\t/**\n\t* Returns a reduced form of style property form normalized object.\n\t*\n\t* For default margin reducer, the below code:\n\t*\n\t* ```ts\n\t* stylesProcessor.getReducedForm( 'margin', {\n\t* \tmargin: { top: '1px', right: '1px', bottom: '2px', left: '1px; }\n\t* } );\n\t* ```\n\t*\n\t* will return:\n\t*\n\t* ```ts\n\t* [\n\t* \t[ 'margin', '1px 1px 2px' ]\n\t* ]\n\t* ```\n\t*\n\t* because it might be represented as a shorthand 'margin' value. However if one of margin long hand values is missing it should return:\n\t*\n\t* ```ts\n\t* [\n\t* \t[ 'margin-top', '1px' ],\n\t* \t[ 'margin-right', '1px' ],\n\t* \t[ 'margin-bottom', '2px' ]\n\t* \t// the 'left' value is missing - cannot use 'margin' shorthand.\n\t* ]\n\t* ```\n\t*\n\t* **Note**: To define reducer callbacks use {@link #setReducer}.\n\t*\n\t* @param name Name of style property.\n\t*/\n\tgetReducedForm(name, styles) {\n\t\tconst normalizedValue = this.getNormalized(name, styles);\n\t\tif (normalizedValue === void 0) return [];\n\t\tif (this._reducers.has(name)) return this._reducers.get(name)(normalizedValue);\n\t\treturn [[name, normalizedValue]];\n\t}\n\t/**\n\t* Return all style properties. Also expand shorthand properties (e.g. `margin`, `background`) if respective extractor is available.\n\t*\n\t* @param styles Object holding normalized styles.\n\t*/\n\tgetStyleNames(styles) {\n\t\tconst styleNamesKeysSet = /* @__PURE__ */ new Set();\n\t\tfor (const name of this._consumables.keys()) {\n\t\t\tconst style = this.getNormalized(name, styles);\n\t\t\tif (style && (typeof style != \"object\" || Object.keys(style).length)) styleNamesKeysSet.add(name);\n\t\t}\n\t\tfor (const name of Object.keys(styles)) styleNamesKeysSet.add(name);\n\t\treturn Array.from(styleNamesKeysSet);\n\t}\n\t/**\n\t* Returns related style names.\n\t*\n\t* ```ts\n\t* stylesProcessor.getRelatedStyles( 'margin' );\n\t* // will return: [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ];\n\t*\n\t* stylesProcessor.getRelatedStyles( 'margin-top' );\n\t* // will return: [ 'margin' ];\n\t* ```\n\t*\n\t* **Note**: To define new style relations load an existing style processor or use\n\t* {@link module:engine/view/stylesmap~StylesProcessor#setStyleRelation `StylesProcessor.setStyleRelation()`}.\n\t*/\n\tgetRelatedStyles(name) {\n\t\treturn this._consumables.get(name) || [];\n\t}\n\t/**\n\t* Adds a normalizer method for a style property.\n\t*\n\t* A normalizer returns describing how the value should be normalized.\n\t*\n\t* For instance 'margin' style is a shorthand for four margin values:\n\t*\n\t* - 'margin-top'\n\t* - 'margin-right'\n\t* - 'margin-bottom'\n\t* - 'margin-left'\n\t*\n\t* and can be written in various ways if some values are equal to others. For instance `'margin: 1px 2em;'` is a shorthand for\n\t* `'margin-top: 1px;margin-right: 2em;margin-bottom: 1px;margin-left: 2em'`.\n\t*\n\t* A normalizer should parse various margin notations as a single object:\n\t*\n\t* ```ts\n\t* const styles = {\n\t* \tmargin: {\n\t* \t\ttop: '1px',\n\t* \t\tright: '2em',\n\t* \t\tbottom: '1px',\n\t* \t\tleft: '2em'\n\t* \t}\n\t* };\n\t* ```\n\t*\n\t* Thus a normalizer for 'margin' style should return an object defining style path and value to store:\n\t*\n\t* ```ts\n\t* const returnValue = {\n\t* \tpath: 'margin',\n\t* \tvalue: {\n\t* \t\ttop: '1px',\n\t* \t\tright: '2em',\n\t* \t\tbottom: '1px',\n\t* \t\tleft: '2em'\n\t* \t}\n\t* };\n\t* ```\n\t*\n\t* Additionally to fully support all margin notations there should be also defined 4 normalizers for longhand margin notations. Below\n\t* is an example for 'margin-top' style property normalizer:\n\t*\n\t* ```ts\n\t* stylesProcessor.setNormalizer( 'margin-top', valueString => {\n\t* \treturn {\n\t* \t\tpath: 'margin.top',\n\t* \t\tvalue: valueString\n\t* \t}\n\t* } );\n\t* ```\n\t*/\n\tsetNormalizer(name, callback) {\n\t\tthis._normalizers.set(name, callback);\n\t}\n\t/**\n\t* Adds a extractor callback for a style property.\n\t*\n\t* Most normalized style values are stored as one level objects. It is assumed that `'margin-top'` style will be stored as:\n\t*\n\t* ```ts\n\t* const styles = {\n\t* \tmargin: {\n\t* \t\ttop: 'value'\n\t* \t}\n\t* }\n\t* ```\n\t*\n\t* However, some styles can have conflicting notations and thus it might be harder to extract a style value from shorthand. For instance\n\t* the 'border-top-style' can be defined using `'border-top:solid'`, `'border-style:solid none none none'` or by `'border:solid'`\n\t* shorthands. The default border styles processors stores styles as:\n\t*\n\t* ```ts\n\t* const styles = {\n\t* \tborder: {\n\t* \t\tstyle: {\n\t* \t\t\ttop: 'solid'\n\t* \t\t}\n\t* \t}\n\t* }\n\t* ```\n\t*\n\t* as it is better to modify border style independently from other values. On the other part the output of the border might be\n\t* desired as `border-top`, `border-left`, etc notation.\n\t*\n\t* In the above example an extractor should return a side border value that combines style, color and width:\n\t*\n\t* ```ts\n\t* styleProcessor.setExtractor( 'border-top', styles => {\n\t* \treturn {\n\t* \t\tcolor: styles.border.color.top,\n\t* \t\tstyle: styles.border.style.top,\n\t* \t\twidth: styles.border.width.top\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* @param callbackOrPath Callback that return a requested value or path string for single values.\n\t*/\n\tsetExtractor(name, callbackOrPath) {\n\t\tthis._extractors.set(name, callbackOrPath);\n\t}\n\t/**\n\t* Adds a reducer callback for a style property.\n\t*\n\t* Reducer returns a minimal notation for given style name. For longhand properties it is not required to write a reducer as\n\t* by default the direct value from style path is taken.\n\t*\n\t* For shorthand styles a reducer should return minimal style notation either by returning single name-value tuple or multiple tuples\n\t* if a shorthand cannot be used. For instance for a margin shorthand a reducer might return:\n\t*\n\t* ```ts\n\t* const marginShortHandTuple = [\n\t* \t[ 'margin', '1px 1px 2px' ]\n\t* ];\n\t* ```\n\t*\n\t* or a longhand tuples for defined values:\n\t*\n\t* ```ts\n\t* // Considering margin.bottom and margin.left are undefined.\n\t* const marginLonghandsTuples = [\n\t* \t[ 'margin-top', '1px' ],\n\t* \t[ 'margin-right', '1px' ]\n\t* ];\n\t* ```\n\t*\n\t* A reducer obtains a normalized style value:\n\t*\n\t* ```ts\n\t* // Simplified reducer that always outputs 4 values which are always present:\n\t* stylesProcessor.setReducer( 'margin', margin => {\n\t* \treturn [\n\t* \t\t[ 'margin', `${ margin.top } ${ margin.right } ${ margin.bottom } ${ margin.left }` ]\n\t* \t]\n\t* } );\n\t* ```\n\t*/\n\tsetReducer(name, callback) {\n\t\tthis._reducers.set(name, callback);\n\t}\n\t/**\n\t* Defines a style shorthand relation to other style notations.\n\t*\n\t* ```ts\n\t* stylesProcessor.setStyleRelation( 'margin', [\n\t* \t'margin-top',\n\t* \t'margin-right',\n\t* \t'margin-bottom',\n\t* \t'margin-left'\n\t* ] );\n\t* ```\n\t*\n\t* This enables expanding of style names for shorthands. For instance, if defined,\n\t* {@link module:engine/conversion/viewconsumable~ViewConsumable view consumable} items are automatically created\n\t* for long-hand margin style notation alongside the `'margin'` item.\n\t*\n\t* This means that when an element being converted has a style `margin`, a converter for `margin-left` will work just\n\t* fine since the view consumable will contain a consumable `margin-left` item (thanks to the relation) and\n\t* `element.getStyle( 'margin-left' )` will work as well assuming that the style processor was correctly configured.\n\t* However, once `margin-left` is consumed, `margin` will not be consumable anymore.\n\t*/\n\tsetStyleRelation(shorthandName, styleNames) {\n\t\tthis._mapStyleNames(shorthandName, styleNames);\n\t\tfor (const alsoName of styleNames) this._mapStyleNames(alsoName, [shorthandName]);\n\t}\n\t/**\n\t* Set two-way binding of style names.\n\t*/\n\t_mapStyleNames(name, styleNames) {\n\t\tif (!this._consumables.has(name)) this._consumables.set(name, []);\n\t\tthis._consumables.get(name).push(...styleNames);\n\t}\n};\n/**\n* Parses inline styles and puts property - value pairs into styles map.\n*\n* @param stylesString Styles to parse.\n* @returns Map of parsed properties and values.\n*/\nfunction parseInlineStyles(stylesString) {\n\tlet quoteType = null;\n\tlet propertyNameStart = 0;\n\tlet propertyValueStart = 0;\n\tlet propertyName = null;\n\tconst stylesMap = /* @__PURE__ */ new Map();\n\tif (stylesString === \"\") return stylesMap;\n\tif (stylesString.charAt(stylesString.length - 1) != \";\") stylesString = stylesString + \";\";\n\tfor (let i = 0; i < stylesString.length; i++) {\n\t\tconst char = stylesString.charAt(i);\n\t\tif (quoteType === null) switch (char) {\n\t\t\tcase \":\":\n\t\t\t\tif (!propertyName) {\n\t\t\t\t\tpropertyName = stylesString.substr(propertyNameStart, i - propertyNameStart);\n\t\t\t\t\tpropertyValueStart = i + 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"\\\"\":\n\t\t\tcase \"'\":\n\t\t\t\tquoteType = char;\n\t\t\t\tbreak;\n\t\t\tcase \";\": {\n\t\t\t\tconst propertyValue = stylesString.substr(propertyValueStart, i - propertyValueStart);\n\t\t\t\tif (propertyName) stylesMap.set(propertyName.trim(), propertyValue.trim());\n\t\t\t\tpropertyName = null;\n\t\t\t\tpropertyNameStart = i + 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (char === quoteType) quoteType = null;\n\t}\n\treturn stylesMap;\n}\n/**\n* Return lodash compatible path from style name.\n*/\nfunction toPath(name) {\n\treturn name.replace(\"-\", \".\");\n}\n/**\n* Appends style definition to the styles object.\n*/\nfunction appendStyleValue(stylesObject, nameOrPath, valueOrObject) {\n\tlet valueToSet = valueOrObject;\n\tif (isObject(valueOrObject) && !Array.isArray(valueOrObject)) valueToSet = merge({}, get(stylesObject, nameOrPath), valueOrObject);\n\tset(stylesObject, nameOrPath, valueToSet);\n}\n/**\n* Modifies the `styles` deeply nested object by removing properties defined in `toRemove`.\n*/\nfunction removeStyles(styles, toRemove) {\n\tfor (const key of Object.keys(toRemove)) if (styles[key] !== null && !Array.isArray(styles[key]) && typeof styles[key] == \"object\" && typeof toRemove[key] == \"object\") {\n\t\tremoveStyles(styles[key], toRemove[key]);\n\t\tif (!Object.keys(styles[key]).length) delete styles[key];\n\t} else delete styles[key];\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/tokenlist\n*/\n/**\n* Token list. Allows handling (adding, removing, retrieving) a set of tokens (for example class names).\n*/\nvar ViewTokenList = class {\n\t/**\n\t* The set of tokens.\n\t*/\n\t_set = /* @__PURE__ */ new Set();\n\t/**\n\t* Returns true if token list has no tokens set.\n\t*/\n\tget isEmpty() {\n\t\treturn this._set.size == 0;\n\t}\n\t/**\n\t* Number of tokens.\n\t*/\n\tget size() {\n\t\treturn this._set.size;\n\t}\n\t/**\n\t* Checks if a given token is set.\n\t*/\n\thas(name) {\n\t\treturn this._set.has(name);\n\t}\n\t/**\n\t* Returns all tokens.\n\t*/\n\tkeys() {\n\t\treturn Array.from(this._set.keys());\n\t}\n\t/**\n\t* Resets the value to the given one.\n\t*/\n\tsetTo(value) {\n\t\tthis.clear();\n\t\tfor (const token of value.split(/\\s+/)) if (token) this._set.add(token);\n\t\treturn this;\n\t}\n\t/**\n\t* Sets a given token without affecting other tokens.\n\t*/\n\tset(tokens) {\n\t\tfor (const token of toArray(tokens)) if (token) this._set.add(token);\n\t}\n\t/**\n\t* Removes given token.\n\t*/\n\tremove(tokens) {\n\t\tfor (const token of toArray(tokens)) this._set.delete(token);\n\t}\n\t/**\n\t* Removes all tokens.\n\t*/\n\tclear() {\n\t\tthis._set.clear();\n\t}\n\t/**\n\t* Returns a normalized tokens string.\n\t*/\n\ttoString() {\n\t\treturn Array.from(this._set).join(\" \");\n\t}\n\t/**\n\t* Returns `true` if both attributes have the same tokens.\n\t*/\n\tisSimilar(other) {\n\t\tif (this.size !== other.size) return false;\n\t\tfor (const token of this.keys()) if (!other.has(token)) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Clones the attribute value.\n\t*\n\t* @internal\n\t*/\n\t_clone() {\n\t\tconst clone = new this.constructor();\n\t\tclone._set = new Set(this._set);\n\t\treturn clone;\n\t}\n\t/**\n\t* Used by the {@link module:engine/view/matcher~Matcher Matcher} to collect matching attribute tokens.\n\t*\n\t* @internal\n\t* @param tokenPattern The matched token name pattern.\n\t* @returns An array of matching tokens.\n\t*/\n\t_getTokensMatch(tokenPattern) {\n\t\tconst match = [];\n\t\tif (tokenPattern === true) {\n\t\t\tfor (const token of this._set.keys()) match.push(token);\n\t\t\treturn match;\n\t\t}\n\t\tif (typeof tokenPattern == \"string\") {\n\t\t\tfor (const token of tokenPattern.split(/\\s+/)) if (this._set.has(token)) match.push(token);\n\t\t\telse return;\n\t\t\treturn match;\n\t\t}\n\t\tfor (const token of this._set.keys()) if (token.match(tokenPattern)) match.push(token);\n\t\treturn match.length ? match : void 0;\n\t}\n\t/**\n\t* Returns a list of consumables for the attribute.\n\t*\n\t* Could be filtered by the given token name.\n\t*\n\t* @internal\n\t*/\n\t_getConsumables(name) {\n\t\treturn name ? [name] : this.keys();\n\t}\n\t/**\n\t* Used by {@link module:engine/view/element~ViewElement#_canMergeAttributesFrom} to verify if the given attribute\n\t* can be merged without conflicts into the attribute.\n\t*\n\t* This method is indirectly used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while downcasting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to merge it with other `AttributeElement`.\n\t*\n\t* @internal\n\t*/\n\t_canMergeFrom() {\n\t\treturn true;\n\t}\n\t/**\n\t* Used by {@link module:engine/view/element~ViewElement#_mergeAttributesFrom} to merge a given attribute into the attribute.\n\t*\n\t* This method is indirectly used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to merge it with other ViewAttributeElement.\n\t*\n\t* @internal\n\t*/\n\t_mergeFrom(other) {\n\t\tfor (const token of other._set.keys()) if (!this._set.has(token)) this._set.add(token);\n\t}\n\t/**\n\t* Used by {@link module:engine/view/element~ViewElement#_canSubtractAttributesOf} to verify if the given attribute\n\t* can be fully subtracted from the attribute.\n\t*\n\t* This method is indirectly used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to unwrap the ViewAttributeElement.\n\t*\n\t* @internal\n\t*/\n\t_isMatching(other) {\n\t\tfor (const name of other._set.keys()) if (!this._set.has(name)) return false;\n\t\treturn true;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/element\n*/\n/**\n* View element.\n*\n* The editing engine does not define a fixed semantics of its elements (it is \"DTD-free\").\n* This is why the type of the {@link module:engine/view/element~ViewElement} need to\n* be defined by the feature developer. When creating an element you should use one of the following methods:\n*\n* * {@link module:engine/view/downcastwriter~ViewDowncastWriter#createContainerElement `downcastWriter#createContainerElement()`}\n* in order to create a {@link module:engine/view/containerelement~ViewContainerElement},\n* * {@link module:engine/view/downcastwriter~ViewDowncastWriter#createAttributeElement `downcastWriter#createAttributeElement()`}\n* in order to create a {@link module:engine/view/attributeelement~ViewAttributeElement},\n* * {@link module:engine/view/downcastwriter~ViewDowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`}\n* in order to create a {@link module:engine/view/emptyelement~ViewEmptyElement}.\n* * {@link module:engine/view/downcastwriter~ViewDowncastWriter#createUIElement `downcastWriter#createUIElement()`}\n* in order to create a {@link module:engine/view/uielement~ViewUIElement}.\n* * {@link module:engine/view/downcastwriter~ViewDowncastWriter#createEditableElement `downcastWriter#createEditableElement()`}\n* in order to create a {@link module:engine/view/editableelement~ViewEditableElement}.\n*\n* Note that for view elements which are not created from the model, like elements from mutations, paste or\n* {@link module:engine/controller/datacontroller~DataController#set data.set} it is not possible to define the type of the element.\n* In such cases the {@link module:engine/view/upcastwriter~ViewUpcastWriter#createElement `UpcastWriter#createElement()`} method\n* should be used to create generic view elements.\n*/\nvar ViewElement = class ViewElement extends ViewNode {\n\t/**\n\t* Name of the element.\n\t*/\n\tname;\n\t/**\n\t* A list of attribute names that should be rendered in the editing pipeline even though filtering mechanisms\n\t* implemented in the {@link module:engine/view/domconverter~ViewDomConverter} (for instance,\n\t* {@link module:engine/view/domconverter~ViewDomConverter#shouldRenderAttribute}) would filter them out.\n\t*\n\t* These attributes can be specified as an option when the element is created by\n\t* the {@link module:engine/view/downcastwriter~ViewDowncastWriter}. To check whether an unsafe an attribute should\n\t* be permitted, use the {@link #shouldRenderUnsafeAttribute} method.\n\t*\n\t* @internal\n\t*/\n\t_unsafeAttributesToRender = [];\n\t/**\n\t* Map of attributes, where attributes names are keys and attributes values are values.\n\t*/\n\t_attrs;\n\t/**\n\t* Array of child nodes.\n\t*/\n\t_children;\n\t/**\n\t* Map of custom properties.\n\t* Custom properties can be added to element instance, will be cloned but not rendered into DOM.\n\t*/\n\t_customProperties = /* @__PURE__ */ new Map();\n\t/**\n\t* Set of classes associated with element instance.\n\t*\n\t* Note that this is just an alias for `this._attrs.get( 'class' );`\n\t*/\n\tget _classes() {\n\t\treturn this._attrs.get(\"class\");\n\t}\n\t/**\n\t* Normalized styles.\n\t*\n\t* Note that this is just an alias for `this._attrs.get( 'style' );`\n\t*/\n\tget _styles() {\n\t\treturn this._attrs.get(\"style\");\n\t}\n\t/**\n\t* Creates a view element.\n\t*\n\t* Attributes can be passed in various formats:\n\t*\n\t* ```ts\n\t* new Element( viewDocument, 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t* new Element( viewDocument, 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t* new Element( viewDocument, 'div', mapOfAttributes ); // map\n\t* ```\n\t*\n\t* @internal\n\t* @param document The document instance to which this element belongs.\n\t* @param name Node name.\n\t* @param attrs Collection of attributes.\n\t* @param children A list of nodes to be inserted into created element.\n\t*/\n\tconstructor(document, name, attrs, children) {\n\t\tsuper(document);\n\t\tthis.name = name;\n\t\tthis._attrs = this._parseAttributes(attrs);\n\t\tthis._children = [];\n\t\tif (children) this._insertChild(0, children);\n\t}\n\t/**\n\t* Number of element's children.\n\t*/\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\t/**\n\t* Is `true` if there are no nodes inside this element, `false` otherwise.\n\t*/\n\tget isEmpty() {\n\t\treturn this._children.length === 0;\n\t}\n\t/**\n\t* Gets child at the given index.\n\t*\n\t* @param index Index of child.\n\t* @returns Child node.\n\t*/\n\tgetChild(index) {\n\t\treturn this._children[index];\n\t}\n\t/**\n\t* Gets index of the given child node. Returns `-1` if child node is not found.\n\t*\n\t* @param node Child node.\n\t* @returns Index of the child node.\n\t*/\n\tgetChildIndex(node) {\n\t\treturn this._children.indexOf(node);\n\t}\n\t/**\n\t* Gets child nodes iterator.\n\t*\n\t* @returns Child nodes iterator.\n\t*/\n\tgetChildren() {\n\t\treturn this._children[Symbol.iterator]();\n\t}\n\t/**\n\t* Returns an iterator that contains the keys for attributes. Order of inserting attributes is not preserved.\n\t*\n\t* @returns Keys for attributes.\n\t*/\n\t*getAttributeKeys() {\n\t\tif (this._classes) yield \"class\";\n\t\tif (this._styles) yield \"style\";\n\t\tfor (const key of this._attrs.keys()) if (key != \"class\" && key != \"style\") yield key;\n\t}\n\t/**\n\t* Returns iterator that iterates over this element's attributes.\n\t*\n\t* Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t* This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t*/\n\t*getAttributes() {\n\t\tfor (const [name, value] of this._attrs.entries()) yield [name, String(value)];\n\t}\n\t/**\n\t* Gets attribute by key. If attribute is not present - returns undefined.\n\t*\n\t* @param key Attribute key.\n\t* @returns Attribute value.\n\t*/\n\tgetAttribute(key) {\n\t\treturn this._attrs.has(key) ? String(this._attrs.get(key)) : void 0;\n\t}\n\t/**\n\t* Returns a boolean indicating whether an attribute with the specified key exists in the element.\n\t*\n\t* @param key Attribute key.\n\t* @returns `true` if attribute with the specified key exists in the element, `false` otherwise.\n\t*/\n\thasAttribute(key, token) {\n\t\tif (!this._attrs.has(key)) return false;\n\t\tif (token !== void 0) if (usesStylesMap(this.name, key) || usesTokenList(this.name, key)) return this._attrs.get(key).has(token);\n\t\telse return this._attrs.get(key) === token;\n\t\treturn true;\n\t}\n\t/**\n\t* Checks if this element is similar to other element.\n\t* Both elements should have the same name and attributes to be considered as similar. Two similar elements\n\t* can contain different set of children nodes.\n\t*/\n\tisSimilar(otherElement) {\n\t\tif (!(otherElement instanceof ViewElement)) return false;\n\t\tif (this === otherElement) return true;\n\t\tif (this.name != otherElement.name) return false;\n\t\tif (this._attrs.size !== otherElement._attrs.size) return false;\n\t\tfor (const [key, value] of this._attrs) {\n\t\t\tconst otherValue = otherElement._attrs.get(key);\n\t\t\tif (otherValue === void 0) return false;\n\t\t\tif (typeof value == \"string\" || typeof otherValue == \"string\") {\n\t\t\t\tif (otherValue !== value) return false;\n\t\t\t} else if (!value.isSimilar(otherValue)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Returns true if class is present.\n\t* If more then one class is provided - returns true only when all classes are present.\n\t*\n\t* ```ts\n\t* element.hasClass( 'foo' ); // Returns true if 'foo' class is present.\n\t* element.hasClass( 'foo', 'bar' ); // Returns true if 'foo' and 'bar' classes are both present.\n\t* ```\n\t*/\n\thasClass(...className) {\n\t\tfor (const name of className) if (!this._classes || !this._classes.has(name)) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Returns iterator that contains all class names.\n\t*/\n\tgetClassNames() {\n\t\tconst array = this._classes ? this._classes.keys() : [];\n\t\tconst iterator = array[Symbol.iterator]();\n\t\treturn Object.assign(array, { next: iterator.next.bind(iterator) });\n\t}\n\t/**\n\t* Returns style value for the given property name.\n\t* If the style does not exist `undefined` is returned.\n\t*\n\t* **Note**: This method can work with normalized style names if\n\t* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t* See {@link module:engine/view/stylesmap~StylesMap#getAsString `StylesMap#getAsString()`} for details.\n\t*\n\t* For an element with style set to `'margin:1px'`:\n\t*\n\t* ```ts\n\t* // Enable 'margin' shorthand processing:\n\t* editor.data.addStyleProcessorRules( addMarginStylesRules );\n\t*\n\t* const element = view.change( writer => {\n\t* \tconst element = writer.createElement();\n\t* \twriter.setStyle( 'margin', '1px' );\n\t* \twriter.setStyle( 'margin-bottom', '3em' );\n\t*\n\t* \treturn element;\n\t* } );\n\t*\n\t* element.getStyle( 'margin' ); // -> 'margin: 1px 1px 3em;'\n\t* ```\n\t*/\n\tgetStyle(property) {\n\t\treturn this._styles && this._styles.getAsString(property);\n\t}\n\t/**\n\t* Returns a normalized style object or single style value.\n\t*\n\t* For an element with style set to: margin:1px 2px 3em;\n\t*\n\t* ```ts\n\t* element.getNormalizedStyle( 'margin' ) );\n\t* ```\n\t*\n\t* will return:\n\t*\n\t* ```ts\n\t* {\n\t* \ttop: '1px',\n\t* \tright: '2px',\n\t* \tbottom: '3em',\n\t* \tleft: '2px' // a normalized value from margin shorthand\n\t* }\n\t* ```\n\t*\n\t* and reading for single style value:\n\t*\n\t* ```ts\n\t* styles.getNormalizedStyle( 'margin-left' );\n\t* ```\n\t*\n\t* Will return a `2px` string.\n\t*\n\t* **Note**: This method will return normalized values only if\n\t* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t* See {@link module:engine/view/stylesmap~StylesMap#getNormalized `StylesMap#getNormalized()`} for details.\n\t*\n\t* @param property Name of CSS property\n\t*/\n\tgetNormalizedStyle(property) {\n\t\treturn this._styles && this._styles.getNormalized(property);\n\t}\n\t/**\n\t* Returns an array that contains all style names.\n\t*\n\t* @param expand Expand shorthand style properties and return all equivalent style representations.\n\t*/\n\tgetStyleNames(expand) {\n\t\treturn this._styles ? this._styles.getStyleNames(expand) : [];\n\t}\n\t/**\n\t* Returns true if style keys are present.\n\t* If more then one style property is provided - returns true only when all properties are present.\n\t*\n\t* ```ts\n\t* element.hasStyle( 'color' ); // Returns true if 'border-top' style is present.\n\t* element.hasStyle( 'color', 'border-top' ); // Returns true if 'color' and 'border-top' styles are both present.\n\t* ```\n\t*/\n\thasStyle(...property) {\n\t\tfor (const name of property) if (!this._styles || !this._styles.has(name)) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Returns ancestor element that match specified pattern.\n\t* Provided patterns should be compatible with {@link module:engine/view/matcher~Matcher Matcher} as it is used internally.\n\t*\n\t* @see module:engine/view/matcher~Matcher\n\t* @param patterns Patterns used to match correct ancestor. See {@link module:engine/view/matcher~Matcher}.\n\t* @returns Found element or `null` if no matching ancestor was found.\n\t*/\n\tfindAncestor(...patterns) {\n\t\tconst matcher = new Matcher(...patterns);\n\t\tlet parent = this.parent;\n\t\twhile (parent && !parent.is(\"documentFragment\")) {\n\t\t\tif (matcher.match(parent)) return parent;\n\t\t\tparent = parent.parent;\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Returns the custom property value for the given key.\n\t*/\n\tgetCustomProperty(key) {\n\t\treturn this._customProperties.get(key);\n\t}\n\t/**\n\t* Returns an iterator which iterates over this element's custom properties.\n\t* Iterator provides `[ key, value ]` pairs for each stored property.\n\t*/\n\t*getCustomProperties() {\n\t\tyield* this._customProperties.entries();\n\t}\n\t/**\n\t* Returns identity string based on element's name, styles, classes and other attributes.\n\t* Two elements that {@link #isSimilar are similar} will have same identity string.\n\t* It has the following format:\n\t*\n\t* ```ts\n\t* 'name class=\"class1,class2\" style=\"style1:value1;style2:value2\" attr1=\"val1\" attr2=\"val2\"'\n\t* ```\n\t*\n\t* For example:\n\t*\n\t* ```ts\n\t* const element = writer.createContainerElement( 'foo', {\n\t* \tbanana: '10',\n\t* \tapple: '20',\n\t* \tstyle: 'color: red; border-color: white;',\n\t* \tclass: 'baz'\n\t* } );\n\t*\n\t* // returns 'foo class=\"baz\" style=\"border-color:white;color:red\" apple=\"20\" banana=\"10\"'\n\t* element.getIdentity();\n\t* ```\n\t*\n\t* **Note**: Classes, styles and other attributes are sorted alphabetically.\n\t*/\n\tgetIdentity() {\n\t\tconst classes = this._classes ? this._classes.keys().sort().join(\",\") : \"\";\n\t\tconst styles = this._styles && String(this._styles);\n\t\tconst attributes = Array.from(this._attrs).filter(([key]) => key != \"style\" && key != \"class\").map((i) => `${i[0]}=\"${i[1]}\"`).sort().join(\" \");\n\t\treturn this.name + (classes == \"\" ? \"\" : ` class=\"${classes}\"`) + (!styles ? \"\" : ` style=\"${styles}\"`) + (attributes == \"\" ? \"\" : ` ${attributes}`);\n\t}\n\t/**\n\t* Decides whether an unsafe attribute is whitelisted and should be rendered in the editing pipeline even though filtering mechanisms\n\t* like {@link module:engine/view/domconverter~ViewDomConverter#shouldRenderAttribute} say it should not.\n\t*\n\t* Unsafe attribute names can be specified when creating an element via {@link module:engine/view/downcastwriter~ViewDowncastWriter}.\n\t*\n\t* @param attributeName The name of the attribute to be checked.\n\t*/\n\tshouldRenderUnsafeAttribute(attributeName) {\n\t\treturn this._unsafeAttributesToRender.includes(attributeName);\n\t}\n\t/**\n\t* Converts `ViewElement` to plain object and returns it.\n\t*\n\t* @returns `ViewElement` converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.name = this.name;\n\t\tjson.type = \"Element\";\n\t\tif (this._attrs.size) json.attributes = Object.fromEntries(this.getAttributes());\n\t\tif (this._children.length > 0) {\n\t\t\tjson.children = [];\n\t\t\tfor (const node of this._children) json.children.push(node.toJSON());\n\t\t}\n\t\treturn json;\n\t}\n\t/**\n\t* Clones provided element.\n\t*\n\t* @internal\n\t* @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t* element will be cloned without any children.\n\t* @returns Clone of this element.\n\t*/\n\t_clone(deep = false) {\n\t\tconst childrenClone = [];\n\t\tif (deep) for (const child of this.getChildren()) childrenClone.push(child._clone(deep));\n\t\tconst cloned = new this.constructor(this.document, this.name, this._attrs, childrenClone);\n\t\tcloned._customProperties = new Map(this._customProperties);\n\t\tcloned.getFillerOffset = this.getFillerOffset;\n\t\tcloned._unsafeAttributesToRender = this._unsafeAttributesToRender;\n\t\treturn cloned;\n\t}\n\t/**\n\t* {@link module:engine/view/element~ViewElement#_insertChild Insert} a child node or a list of child nodes at the end of this node\n\t* and sets the parent of these nodes to this element.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#insert\n\t* @internal\n\t* @param items Items to be inserted.\n\t* @fires change\n\t* @returns Number of appended nodes.\n\t*/\n\t_appendChild(items) {\n\t\treturn this._insertChild(this.childCount, items);\n\t}\n\t/**\n\t* Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t* this element.\n\t*\n\t* @internal\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#insert\n\t* @param index Position where nodes should be inserted.\n\t* @param items Items to be inserted.\n\t* @fires change\n\t* @returns Number of inserted nodes.\n\t*/\n\t_insertChild(index, items) {\n\t\tthis._fireChange(\"children\", this, { index });\n\t\tlet count = 0;\n\t\tconst nodes = normalize$3(this.document, items);\n\t\tfor (const node of nodes) {\n\t\t\tif (node.parent !== null) node._remove();\n\t\t\tnode.parent = this;\n\t\t\tnode.document = this.document;\n\t\t\tthis._children.splice(index, 0, node);\n\t\t\tindex++;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\t/**\n\t* Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#remove\n\t* @internal\n\t* @param index Number of the first node to remove.\n\t* @param howMany Number of nodes to remove.\n\t* @fires change\n\t* @returns The array of removed nodes.\n\t*/\n\t_removeChildren(index, howMany = 1) {\n\t\tthis._fireChange(\"children\", this, { index });\n\t\tfor (let i = index; i < index + howMany; i++) this._children[i].parent = null;\n\t\treturn this._children.splice(index, howMany);\n\t}\n\t/**\n\t* Adds or overwrite attribute with a specified key and value.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#setAttribute\n\t* @internal\n\t* @param key Attribute key.\n\t* @param value Attribute value.\n\t* @param overwrite Whether tokenized attribute should override the attribute value or just add a token.\n\t* @fires change\n\t*/\n\t_setAttribute(key, value, overwrite = true) {\n\t\tthis._fireChange(\"attributes\", this);\n\t\tif (usesStylesMap(this.name, key) || usesTokenList(this.name, key)) {\n\t\t\tlet currentValue = this._attrs.get(key);\n\t\t\tif (!currentValue) {\n\t\t\t\tcurrentValue = usesStylesMap(this.name, key) ? new StylesMap(this.document.stylesProcessor) : new ViewTokenList();\n\t\t\t\tthis._attrs.set(key, currentValue);\n\t\t\t}\n\t\t\tif (overwrite) currentValue.setTo(String(value));\n\t\t\telse if (usesStylesMap(this.name, key)) if (Array.isArray(value)) currentValue.set(value[0], value[1]);\n\t\t\telse currentValue.set(value);\n\t\t\telse currentValue.set(typeof value == \"string\" ? value.split(/\\s+/) : value);\n\t\t} else this._attrs.set(key, String(value));\n\t}\n\t/**\n\t* Removes attribute from the element.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#removeAttribute\n\t* @internal\n\t* @param key Attribute key.\n\t* @param tokens Attribute value tokens to remove. The whole attribute is removed if not specified.\n\t* @returns Returns true if an attribute existed and has been removed.\n\t* @fires change\n\t*/\n\t_removeAttribute(key, tokens) {\n\t\tthis._fireChange(\"attributes\", this);\n\t\tif (tokens !== void 0 && (usesStylesMap(this.name, key) || usesTokenList(this.name, key))) {\n\t\t\tconst currentValue = this._attrs.get(key);\n\t\t\tif (!currentValue) return false;\n\t\t\tif (usesTokenList(this.name, key) && typeof tokens == \"string\") tokens = tokens.split(/\\s+/);\n\t\t\tcurrentValue.remove(tokens);\n\t\t\tif (currentValue.isEmpty) return this._attrs.delete(key);\n\t\t\treturn false;\n\t\t}\n\t\treturn this._attrs.delete(key);\n\t}\n\t/**\n\t* Adds specified class.\n\t*\n\t* ```ts\n\t* element._addClass( 'foo' ); // Adds 'foo' class.\n\t* element._addClass( [ 'foo', 'bar' ] ); // Adds 'foo' and 'bar' classes.\n\t* ```\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#addClass\n\t* @internal\n\t* @fires change\n\t*/\n\t_addClass(className) {\n\t\tthis._setAttribute(\"class\", className, false);\n\t}\n\t/**\n\t* Removes specified class.\n\t*\n\t* ```ts\n\t* element._removeClass( 'foo' ); // Removes 'foo' class.\n\t* element._removeClass( [ 'foo', 'bar' ] ); // Removes both 'foo' and 'bar' classes.\n\t* ```\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#removeClass\n\t* @internal\n\t* @fires change\n\t*/\n\t_removeClass(className) {\n\t\tthis._removeAttribute(\"class\", className);\n\t}\n\t_setStyle(property, value) {\n\t\tif (typeof property != \"string\") this._setAttribute(\"style\", property, false);\n\t\telse this._setAttribute(\"style\", [property, value], false);\n\t}\n\t/**\n\t* Removes specified style.\n\t*\n\t* ```ts\n\t* element._removeStyle( 'color' ); // Removes 'color' style.\n\t* element._removeStyle( [ 'color', 'border-top' ] ); // Removes both 'color' and 'border-top' styles.\n\t* ```\n\t*\n\t* **Note**: This method can work with normalized style names if\n\t* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t* See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#removeStyle\n\t* @internal\n\t* @fires change\n\t*/\n\t_removeStyle(property) {\n\t\tthis._removeAttribute(\"style\", property);\n\t}\n\t/**\n\t* Used by the {@link module:engine/view/matcher~Matcher Matcher} to collect matching attribute tuples\n\t* (attribute name and optional token).\n\t*\n\t* Normalized patterns can be used in following ways:\n\t* - to match any attribute name with any or no value:\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ true, true ]\n\t* ]\n\t* ```\n\t*\n\t* - to match a specific attribute with any value:\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ 'required', true ]\n\t* ]\n\t* ```\n\t*\n\t* - to match an attribute name with a RegExp with any value:\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ /h[1-6]/, true ]\n\t* ]\n\t* ```\n\t*\n\t* \t- to match a specific attribute with the exact value:\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ 'rel', 'nofollow' ]\n\t* ]\n\t* ```\n\t*\n\t* \t- to match a specific attribute with a value matching a RegExp:\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ 'src', /^https/ ]\n\t* ]\n\t* ```\n\t*\n\t* \t- to match an attribute name with a RegExp and the exact value:\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ /^data-property-/, 'foobar' ],\n\t* ]\n\t* ```\n\t*\n\t* \t- to match an attribute name with a RegExp and match a value with another RegExp:\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ /^data-property-/, /^foo/ ]\n\t* ]\n\t* ```\n\t*\n\t* \t- to match a specific style property with the value matching a RegExp:\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ 'style', 'font-size', /px$/ ]\n\t* ]\n\t* ```\n\t*\n\t* \t- to match a specific class (class attribute is tokenized so it matches tokens individually):\n\t*\n\t* ```ts\n\t* patterns: [\n\t* \t[ 'class', 'foo' ]\n\t* ]\n\t* ```\n\t*\n\t* @internal\n\t* @param patterns An array of normalized patterns (tuples of 2 or 3 items depending on if tokenized attribute value match is needed).\n\t* @param match An array to populate with matching tuples.\n\t* @param exclude Array of attribute names to exclude from match.\n\t* @returns `true` if element matches all patterns. The matching tuples are pushed to the `match` array.\n\t*/\n\t_collectAttributesMatch(patterns, match, exclude) {\n\t\tfor (const [keyPattern, tokenPattern, valuePattern] of patterns) {\n\t\t\tlet hasKey = false;\n\t\t\tlet hasValue = false;\n\t\t\tfor (const [key, value] of this._attrs) {\n\t\t\t\tif (exclude && exclude.includes(key) || !isPatternMatched(keyPattern, key)) continue;\n\t\t\t\thasKey = true;\n\t\t\t\tif (typeof value == \"string\") {\n\t\t\t\t\tif (isPatternMatched(tokenPattern, value)) {\n\t\t\t\t\t\tmatch.push([key]);\n\t\t\t\t\t\thasValue = true;\n\t\t\t\t\t} else if (!(keyPattern instanceof RegExp)) return false;\n\t\t\t\t} else {\n\t\t\t\t\tconst tokenMatch = value._getTokensMatch(tokenPattern, valuePattern || true);\n\t\t\t\t\tif (tokenMatch) {\n\t\t\t\t\t\thasValue = true;\n\t\t\t\t\t\tfor (const tokenMatchItem of tokenMatch) match.push([key, tokenMatchItem]);\n\t\t\t\t\t} else if (!(keyPattern instanceof RegExp)) return false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!hasKey || !hasValue) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Used by the {@link module:engine/conversion/viewconsumable~ViewConsumable} to collect the\n\t* {@link module:engine/view/element~ViewNormalizedConsumables} for the element.\n\t*\n\t* When `key` and `token` parameters are provided the output is filtered for the specified attribute and it's tokens and related tokens.\n\t*\n\t* @internal\n\t* @param key Attribute name.\n\t* @param token Reference token to collect all related tokens.\n\t*/\n\t_getConsumables(key, token) {\n\t\tconst attributes = [];\n\t\tif (key) {\n\t\t\tconst value = this._attrs.get(key);\n\t\t\tif (value !== void 0) if (typeof value == \"string\") attributes.push([key]);\n\t\t\telse for (const prop of value._getConsumables(token)) attributes.push([key, prop]);\n\t\t} else for (const [key, value] of this._attrs) if (typeof value == \"string\") attributes.push([key]);\n\t\telse for (const prop of value._getConsumables()) attributes.push([key, prop]);\n\t\treturn {\n\t\t\tname: !key,\n\t\t\tattributes\n\t\t};\n\t}\n\t/**\n\t* Verify if the given element can be merged without conflicts into the element.\n\t*\n\t* Note that this method is extended by the {@link module:engine/view/attributeelement~ViewAttributeElement} implementation.\n\t*\n\t* This method is used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to merge it with other ViewAttributeElement.\n\t*\n\t* @internal\n\t* @returns Returns `true` if elements can be merged.\n\t*/\n\t_canMergeAttributesFrom(otherElement) {\n\t\tif (this.name != otherElement.name) return false;\n\t\tfor (const [key, otherValue] of otherElement._attrs) {\n\t\t\tconst value = this._attrs.get(key);\n\t\t\tif (value === void 0) continue;\n\t\t\tif (typeof value == \"string\" || typeof otherValue == \"string\") {\n\t\t\t\tif (value !== otherValue) return false;\n\t\t\t} else if (!value._canMergeFrom(otherValue)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Merges attributes of a given element into the element.\n\t* This includes also tokenized attributes like style and class.\n\t*\n\t* Note that you should make sure there are no conflicts before merging (see {@link #_canMergeAttributesFrom}).\n\t*\n\t* This method is used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to merge it with other ViewAttributeElement.\n\t*\n\t* @internal\n\t*/\n\t_mergeAttributesFrom(otherElement) {\n\t\tthis._fireChange(\"attributes\", this);\n\t\tfor (const [key, otherValue] of otherElement._attrs) {\n\t\t\tconst value = this._attrs.get(key);\n\t\t\tif (value === void 0 || typeof value == \"string\" || typeof otherValue == \"string\") this._setAttribute(key, otherValue);\n\t\t\telse value._mergeFrom(otherValue);\n\t\t}\n\t}\n\t/**\n\t* Verify if the given element attributes can be fully subtracted from the element.\n\t*\n\t* Note that this method is extended by the {@link module:engine/view/attributeelement~ViewAttributeElement} implementation.\n\t*\n\t* This method is used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to unwrap the ViewAttributeElement.\n\t*\n\t* @internal\n\t* @returns Returns `true` if elements attributes can be fully subtracted.\n\t*/\n\t_canSubtractAttributesOf(otherElement) {\n\t\tif (this.name != otherElement.name) return false;\n\t\tfor (const [key, otherValue] of otherElement._attrs) {\n\t\t\tconst value = this._attrs.get(key);\n\t\t\tif (value === void 0) return false;\n\t\t\tif (typeof value == \"string\" || typeof otherValue == \"string\") {\n\t\t\t\tif (value !== otherValue) return false;\n\t\t\t} else if (!value._isMatching(otherValue)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Removes (subtracts) corresponding attributes of the given element from the element.\n\t* This includes also tokenized attributes like style and class.\n\t* All attributes, classes and styles from given element should be present inside the element being unwrapped.\n\t*\n\t* Note that you should make sure all attributes could be subtracted before subtracting them (see {@link #_canSubtractAttributesOf}).\n\t*\n\t* This method is used by the {@link module:engine/view/downcastwriter~ViewDowncastWriter} while down-casting\n\t* an {@link module:engine/view/attributeelement~ViewAttributeElement} to unwrap the ViewAttributeElement.\n\t*\n\t* @internal\n\t*/\n\t_subtractAttributesOf(otherElement) {\n\t\tthis._fireChange(\"attributes\", this);\n\t\tfor (const [key, otherValue] of otherElement._attrs) {\n\t\t\tconst value = this._attrs.get(key);\n\t\t\tif (typeof value == \"string\" || typeof otherValue == \"string\") this._attrs.delete(key);\n\t\t\telse {\n\t\t\t\tvalue.remove(otherValue.keys());\n\t\t\t\tif (value.isEmpty) this._attrs.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* Sets a custom property. Unlike attributes, custom properties are not rendered to the DOM,\n\t* so they can be used to add special data to elements.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#setCustomProperty\n\t* @internal\n\t*/\n\t_setCustomProperty(key, value) {\n\t\tthis._customProperties.set(key, value);\n\t}\n\t/**\n\t* Removes the custom property stored under the given key.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#removeCustomProperty\n\t* @internal\n\t* @returns Returns true if property was removed.\n\t*/\n\t_removeCustomProperty(key) {\n\t\treturn this._customProperties.delete(key);\n\t}\n\t/**\n\t* Parses attributes provided to the element constructor before they are applied to an element. If attributes are passed\n\t* as an object (instead of `Iterable`), the object is transformed to the map. Attributes with `null` value are removed.\n\t* Attributes with non-`String` value are converted to `String`.\n\t*\n\t* @param attrs Attributes to parse.\n\t* @returns Parsed attributes.\n\t*/\n\t_parseAttributes(attrs) {\n\t\tconst attrsMap = toMap(attrs);\n\t\tfor (const [key, value] of attrsMap) if (value === null) attrsMap.delete(key);\n\t\telse if (usesStylesMap(this.name, key)) {\n\t\t\tconst newValue = value instanceof StylesMap ? value._clone() : new StylesMap(this.document.stylesProcessor).setTo(String(value));\n\t\t\tattrsMap.set(key, newValue);\n\t\t} else if (usesTokenList(this.name, key)) {\n\t\t\tconst newValue = value instanceof ViewTokenList ? value._clone() : new ViewTokenList().setTo(String(value));\n\t\t\tattrsMap.set(key, newValue);\n\t\t} else if (typeof value != \"string\") attrsMap.set(key, String(value));\n\t\treturn attrsMap;\n\t}\n};\nViewElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"element\" || type === \"view:element\" || type === \"node\" || type === \"view:node\";\n\telse return name === this.name && (type === \"element\" || type === \"view:element\");\n};\n/**\n* Converts strings to Text and non-iterables to arrays.\n*/\nfunction normalize$3(document, nodes) {\n\tif (typeof nodes == \"string\") return [new ViewText(document, nodes)];\n\tif (!isIterable(nodes)) nodes = [nodes];\n\tconst normalizedNodes = [];\n\tfor (const node of nodes) if (typeof node == \"string\") normalizedNodes.push(new ViewText(document, node));\n\telse if (node instanceof ViewTextProxy) normalizedNodes.push(new ViewText(document, node.data));\n\telse normalizedNodes.push(node);\n\treturn normalizedNodes;\n}\n/**\n* Returns `true` if an attribute on a given element should be handled as a TokenList.\n*/\nfunction usesTokenList(elementName, key) {\n\treturn key == \"class\" || elementName == \"a\" && key == \"rel\";\n}\n/**\n* Returns `true` if an attribute on a given element should be handled as a StylesMap.\n*/\nfunction usesStylesMap(elementName, key) {\n\treturn key == \"style\";\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/containerelement\n*/\n/**\n* Containers are elements which define document structure. They define boundaries for\n* {@link module:engine/view/attributeelement~ViewAttributeElement attributes}.\n* They are mostly used for block elements like `<p>` or `<div>`.\n*\n* Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various\n* types (container element, {@link module:engine/view/attributeelement~ViewAttributeElement attribute element},\n* {@link module:engine/view/emptyelement~ViewEmptyElement empty element}, etc) when developing a feature.\n*\n* The container element should be your default choice when writing a converter, unless:\n*\n* * this element represents a model text attribute (then use {@link module:engine/view/attributeelement~ViewAttributeElement}),\n* * this is an empty element like `<img>` (then use {@link module:engine/view/emptyelement~ViewEmptyElement}),\n* * this is a root element,\n* * this is a nested editable element (then use {@link module:engine/view/editableelement~ViewEditableElement}).\n*\n* To create a new container element instance use the\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createContainerElement `ViewDowncastWriter#createContainerElement()`}\n* method.\n*/\nvar ViewContainerElement = class extends ViewElement {\n\t/**\n\t* Creates a container element.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#createContainerElement\n\t* @see module:engine/view/element~ViewElement\n\t* @internal\n\t* @param document The document instance to which this element belongs.\n\t* @param name Node name.\n\t* @param attrs Collection of attributes.\n\t* @param children A list of nodes to be inserted into created element.\n\t*/\n\tconstructor(document, name, attrs, children) {\n\t\tsuper(document, name, attrs, children);\n\t\tthis.getFillerOffset = getViewFillerOffset;\n\t}\n\t/**\n\t* Converts `ViewContainerElement` instance to plain object and returns it.\n\t*\n\t* @returns `ViewContainerElement` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.type = \"ContainerElement\";\n\t\treturn json;\n\t}\n};\nViewContainerElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"containerElement\" || type === \"view:containerElement\" || type === \"element\" || type === \"view:element\" || type === \"node\" || type === \"view:node\";\n\telse return name === this.name && (type === \"containerElement\" || type === \"view:containerElement\" || type === \"element\" || type === \"view:element\");\n};\n/**\n* Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n*\n* @returns Block filler offset or `null` if block filler is not needed.\n*/\nfunction getViewFillerOffset() {\n\tconst children = [...this.getChildren()];\n\tlet lastChild = children[this.childCount - 1];\n\tif (lastChild && lastChild.is(\"element\", \"br\")) return this.childCount;\n\twhile (lastChild && lastChild.is(\"attributeElement\")) {\n\t\tlastChild = lastChild.getChild(lastChild.childCount - 1);\n\t\tif (lastChild && lastChild.is(\"element\", \"br\")) return this.childCount;\n\t}\n\tfor (const child of children) if (!child.is(\"uiElement\")) return null;\n\treturn this.childCount;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/editableelement\n*/\nconst ViewEditableElementBase = /* #__PURE__ */ ObservableMixin(ViewContainerElement);\n/**\n* Editable element which can be a {@link module:engine/view/rooteditableelement~ViewRootEditableElement root}\n* or nested editable area in the editor.\n*\n* Editable is automatically read-only when its {@link module:engine/view/document~ViewDocument Document} is read-only.\n*\n* The constructor of this class shouldn't be used directly. To create new `ViewEditableElement` use the\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createEditableElement `downcastWriter#createEditableElement()`} method.\n*/\nvar ViewEditableElement = class extends ViewEditableElementBase {\n\t/**\n\t* Creates an editable element.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#createEditableElement\n\t* @internal\n\t* @param document The document instance to which this element belongs.\n\t* @param name Node name.\n\t* @param attributes Collection of attributes.\n\t* @param children A list of nodes to be inserted into created element.\n\t*/\n\tconstructor(document, name, attributes, children) {\n\t\tsuper(document, name, attributes, children);\n\t\tthis.set(\"isReadOnly\", false);\n\t\tthis.set(\"isFocused\", false);\n\t\tthis.set(\"placeholder\", void 0);\n\t\tthis.bind(\"isReadOnly\").to(document);\n\t\tthis.bind(\"isFocused\").to(document, \"isFocused\", (isFocused) => isFocused && document.selection.editableElement == this);\n\t\tthis.listenTo(document.selection, \"change\", () => {\n\t\t\tthis.isFocused = document.isFocused && document.selection.editableElement == this;\n\t\t});\n\t}\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Converts `ViewEditableElement` instance to plain object and returns it.\n\t*\n\t* @returns `ViewEditableElement` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.type = \"EditableElement\";\n\t\tjson.isReadOnly = this.isReadOnly;\n\t\tjson.isFocused = this.isFocused;\n\t\treturn json;\n\t}\n};\nViewEditableElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"editableElement\" || type === \"view:editableElement\" || type === \"containerElement\" || type === \"view:containerElement\" || type === \"element\" || type === \"view:element\" || type === \"node\" || type === \"view:node\";\n\telse return name === this.name && (type === \"editableElement\" || type === \"view:editableElement\" || type === \"containerElement\" || type === \"view:containerElement\" || type === \"element\" || type === \"view:element\");\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/rooteditableelement\n*/\nconst rootNameSymbol = Symbol(\"rootName\");\n/**\n* Class representing a single root in the data view. A root can be either\n* {@link ~ViewRootEditableElement#isReadOnly editable or read-only},\n* but in both cases it is called \"an editable\". Roots can contain other {@link module:engine/view/editableelement~ViewEditableElement\n* editable elements} making them \"nested editables\".\n*/\nvar ViewRootEditableElement = class extends ViewEditableElement {\n\t/**\n\t* Creates root editable element.\n\t*\n\t* @param document The document instance to which this element belongs.\n\t* @param name Node name.\n\t*/\n\tconstructor(document, name) {\n\t\tsuper(document, name);\n\t\tthis.rootName = \"main\";\n\t}\n\t/**\n\t* Name of this root inside {@link module:engine/view/document~ViewDocument} that is an owner of this root. If no\n\t* other name is set, `main` name is used.\n\t*\n\t* @readonly\n\t*/\n\tget rootName() {\n\t\treturn this.getCustomProperty(rootNameSymbol);\n\t}\n\tset rootName(rootName) {\n\t\tthis._setCustomProperty(rootNameSymbol, rootName);\n\t}\n\t/**\n\t* Converts `ViewRootEditableElement` instance to string and returns it.\n\t*\n\t* @returns `ViewRootEditableElement` instance converted to string.\n\t*/\n\ttoJSON() {\n\t\treturn this.rootName;\n\t}\n\t/**\n\t* Overrides old element name and sets new one.\n\t* This is needed because view roots are created before they are attached to the DOM.\n\t* The name of the root element is temporary at this stage. It has to be changed when the\n\t* view root element is attached to the DOM element.\n\t*\n\t* @internal\n\t* @param name The new name of element.\n\t*/\n\tset _name(name) {\n\t\tthis.name = name;\n\t}\n};\nViewRootEditableElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"rootElement\" || type === \"view:rootElement\" || type === \"editableElement\" || type === \"view:editableElement\" || type === \"containerElement\" || type === \"view:containerElement\" || type === \"element\" || type === \"view:element\" || type === \"node\" || type === \"view:node\";\n\telse return name === this.name && (type === \"rootElement\" || type === \"view:rootElement\" || type === \"editableElement\" || type === \"view:editableElement\" || type === \"containerElement\" || type === \"view:containerElement\" || type === \"element\" || type === \"view:element\");\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Position iterator class. It allows to iterate forward and backward over the document.\n*/\nvar ViewTreeWalker = class {\n\t/**\n\t* Walking direction. Defaults `'forward'`.\n\t*/\n\tdirection;\n\t/**\n\t* Iterator boundaries.\n\t*\n\t* When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t* on the start of boundary, then `{ done: true }` is returned.\n\t*\n\t* If boundaries are not defined they are set before first and after last child of the root node.\n\t*/\n\tboundaries;\n\t/**\n\t* Flag indicating whether all characters from {@link module:engine/view/text~ViewText} should be returned as one\n\t* {@link module:engine/view/text~ViewText} or one by one as {@link module:engine/view/textproxy~ViewTextProxy}.\n\t*/\n\tsingleCharacters;\n\t/**\n\t* Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t* iterated node will not be returned along with `elementEnd` tag.\n\t*/\n\tshallow;\n\t/**\n\t* Flag indicating whether iterator should ignore `elementEnd` tags. If set to `true`, walker will not\n\t* return a parent node of the start position. Each {@link module:engine/view/element~ViewElement} will be returned once.\n\t* When set to `false` each element might be returned twice: for `'elementStart'` and `'elementEnd'`.\n\t*/\n\tignoreElementEnd;\n\t/**\n\t* Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t* `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t*/\n\t_position;\n\t/**\n\t* Start boundary parent.\n\t*/\n\t_boundaryStartParent;\n\t/**\n\t* End boundary parent.\n\t*/\n\t_boundaryEndParent;\n\t/**\n\t* Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t*\n\t* @param options Object with configuration.\n\t*/\n\tconstructor(options = {}) {\n\t\tif (!options.boundaries && !options.startPosition)\n /**\n\t\t* Neither boundaries nor starting position have been defined.\n\t\t*\n\t\t* @error view-tree-walker-no-start-position\n\t\t*/\n\t\tthrow new CKEditorError(\"view-tree-walker-no-start-position\", null);\n\t\tif (options.direction && options.direction != \"forward\" && options.direction != \"backward\")\n /**\n\t\t* Only `backward` and `forward` direction allowed.\n\t\t*\n\t\t* @error view-tree-walker-unknown-direction\n\t\t*/\n\t\tthrow new CKEditorError(\"view-tree-walker-unknown-direction\", options.startPosition, { direction: options.direction });\n\t\tthis.boundaries = options.boundaries || null;\n\t\tif (options.startPosition) this._position = ViewPosition._createAt(options.startPosition);\n\t\telse this._position = ViewPosition._createAt(options.boundaries[options.direction == \"backward\" ? \"end\" : \"start\"]);\n\t\tthis.direction = options.direction || \"forward\";\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\t\tthis.shallow = !!options.shallow;\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\t}\n\t/**\n\t* Iterable interface.\n\t*/\n\t[Symbol.iterator]() {\n\t\treturn this;\n\t}\n\t/**\n\t* Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t* `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t*/\n\tget position() {\n\t\treturn this._position;\n\t}\n\t/**\n\t* Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t*\n\t* For example:\n\t*\n\t* ```ts\n\t* walker.skip( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t* walker.skip( value => true ); // Move the position to the end: <p>{}foo</p> -> <p>foo</p>[]\n\t* walker.skip( value => false ); // Do not move the position.\n\t* ```\n\t*\n\t* @param skip Callback function. Gets {@link module:engine/view/treewalker~ViewTreeWalkerValue} and should\n\t* return `true` if the value should be skipped or `false` if not.\n\t*/\n\tskip(skip) {\n\t\tlet nextResult;\n\t\tlet prevPosition;\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\t\t\tnextResult = this.next();\n\t\t} while (!nextResult.done && skip(nextResult.value));\n\t\tif (!nextResult.done) this._position = prevPosition;\n\t}\n\t/**\n\t* Moves tree walker {@link #position} to provided `position`. Tree walker will\n\t* continue traversing from that position.\n\t*\n\t* Note: in contrary to {@link ~ViewTreeWalker#skip}, this method does not iterate over the nodes along the way.\n\t* It simply sets the current tree walker position to a new one.\n\t* From the performance standpoint, it is better to use {@link ~ViewTreeWalker#jumpTo} rather than {@link ~ViewTreeWalker#skip}.\n\t*\n\t* If the provided position is before the start boundary, the position will be\n\t* set to the start boundary. If the provided position is after the end boundary,\n\t* the position will be set to the end boundary.\n\t* This is done to prevent the treewalker from traversing outside the boundaries.\n\t*\n\t* @param position Position to jump to.\n\t*/\n\tjumpTo(position) {\n\t\tif (this._boundaryStartParent && position.isBefore(this.boundaries.start)) position = this.boundaries.start;\n\t\telse if (this._boundaryEndParent && position.isAfter(this.boundaries.end)) position = this.boundaries.end;\n\t\tthis._position = position.clone();\n\t}\n\t/**\n\t* Gets the next tree walker's value.\n\t*\n\t* @returns Object implementing iterator interface, returning\n\t* information about taken step.\n\t*/\n\tnext() {\n\t\tif (this.direction == \"forward\") return this._next();\n\t\telse return this._previous();\n\t}\n\t/**\n\t* Makes a step forward in view. Moves the {@link #position} to the next position and returns the encountered value.\n\t*/\n\t_next() {\n\t\tlet position = this.position.clone();\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\t\tif (parent.parent === null && position.offset === parent.childCount) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tif (parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tlet node;\n\t\tif (parent && parent.is(\"view:$text\")) {\n\t\t\tif (position.isAtEnd) {\n\t\t\t\tthis._position = ViewPosition._createAfter(parent);\n\t\t\t\treturn this._next();\n\t\t\t}\n\t\t\tnode = parent.data[position.offset];\n\t\t} else node = parent.getChild(position.offset);\n\t\tif (typeof node == \"string\") {\n\t\t\tlet textLength;\n\t\t\tif (this.singleCharacters) textLength = 1;\n\t\t\telse textLength = (parent === this._boundaryEndParent ? this.boundaries.end.offset : parent.data.length) - position.offset;\n\t\t\tconst textProxy = new ViewTextProxy(parent, position.offset, textLength);\n\t\t\tposition.offset += textLength;\n\t\t\tthis._position = position;\n\t\t\treturn this._formatReturnValue(\"text\", textProxy, previousPosition, position, textLength);\n\t\t}\n\t\tif (node && node.is(\"view:element\")) {\n\t\t\tif (!this.shallow) position = new ViewPosition(node, 0);\n\t\t\telse {\n\t\t\t\tif (this.boundaries && this.boundaries.end.isBefore(position)) return {\n\t\t\t\t\tdone: true,\n\t\t\t\t\tvalue: void 0\n\t\t\t\t};\n\t\t\t\tposition.offset++;\n\t\t\t}\n\t\t\tthis._position = position;\n\t\t\treturn this._formatReturnValue(\"elementStart\", node, previousPosition, position, 1);\n\t\t}\n\t\tif (node && node.is(\"view:$text\")) {\n\t\t\tif (this.singleCharacters) {\n\t\t\t\tposition = new ViewPosition(node, 0);\n\t\t\t\tthis._position = position;\n\t\t\t\treturn this._next();\n\t\t\t}\n\t\t\tlet charactersCount = node.data.length;\n\t\t\tlet item;\n\t\t\tif (node == this._boundaryEndParent) {\n\t\t\t\tcharactersCount = this.boundaries.end.offset;\n\t\t\t\titem = new ViewTextProxy(node, 0, charactersCount);\n\t\t\t\tposition = ViewPosition._createAfter(item);\n\t\t\t} else {\n\t\t\t\titem = new ViewTextProxy(node, 0, node.data.length);\n\t\t\t\tposition.offset++;\n\t\t\t}\n\t\t\tthis._position = position;\n\t\t\treturn this._formatReturnValue(\"text\", item, previousPosition, position, charactersCount);\n\t\t}\n\t\tposition = ViewPosition._createAfter(parent);\n\t\tthis._position = position;\n\t\tif (this.ignoreElementEnd) return this._next();\n\t\treturn this._formatReturnValue(\"elementEnd\", parent, previousPosition, position);\n\t}\n\t/**\n\t* Makes a step backward in view. Moves the {@link #position} to the previous position and returns the encountered value.\n\t*/\n\t_previous() {\n\t\tlet position = this.position.clone();\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\t\tif (parent.parent === null && position.offset === 0) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tif (parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tlet node;\n\t\tif (parent.is(\"view:$text\")) {\n\t\t\tif (position.isAtStart) {\n\t\t\t\tthis._position = ViewPosition._createBefore(parent);\n\t\t\t\treturn this._previous();\n\t\t\t}\n\t\t\tnode = parent.data[position.offset - 1];\n\t\t} else node = parent.getChild(position.offset - 1);\n\t\tif (typeof node == \"string\") {\n\t\t\tlet textLength;\n\t\t\tif (!this.singleCharacters) {\n\t\t\t\tconst startOffset = parent === this._boundaryStartParent ? this.boundaries.start.offset : 0;\n\t\t\t\ttextLength = position.offset - startOffset;\n\t\t\t} else textLength = 1;\n\t\t\tposition.offset -= textLength;\n\t\t\tconst textProxy = new ViewTextProxy(parent, position.offset, textLength);\n\t\t\tthis._position = position;\n\t\t\treturn this._formatReturnValue(\"text\", textProxy, previousPosition, position, textLength);\n\t\t}\n\t\tif (node && node.is(\"view:element\")) {\n\t\t\tif (this.shallow) {\n\t\t\t\tposition.offset--;\n\t\t\t\tthis._position = position;\n\t\t\t\treturn this._formatReturnValue(\"elementStart\", node, previousPosition, position, 1);\n\t\t\t}\n\t\t\tposition = new ViewPosition(node, node.childCount);\n\t\t\tthis._position = position;\n\t\t\tif (this.ignoreElementEnd) return this._previous();\n\t\t\treturn this._formatReturnValue(\"elementEnd\", node, previousPosition, position);\n\t\t}\n\t\tif (node && node.is(\"view:$text\")) {\n\t\t\tif (this.singleCharacters) {\n\t\t\t\tposition = new ViewPosition(node, node.data.length);\n\t\t\t\tthis._position = position;\n\t\t\t\treturn this._previous();\n\t\t\t}\n\t\t\tlet charactersCount = node.data.length;\n\t\t\tlet item;\n\t\t\tif (node == this._boundaryStartParent) {\n\t\t\t\tconst offset = this.boundaries.start.offset;\n\t\t\t\titem = new ViewTextProxy(node, offset, node.data.length - offset);\n\t\t\t\tcharactersCount = item.data.length;\n\t\t\t\tposition = ViewPosition._createBefore(item);\n\t\t\t} else {\n\t\t\t\titem = new ViewTextProxy(node, 0, node.data.length);\n\t\t\t\tposition.offset--;\n\t\t\t}\n\t\t\tthis._position = position;\n\t\t\treturn this._formatReturnValue(\"text\", item, previousPosition, position, charactersCount);\n\t\t}\n\t\tposition = ViewPosition._createBefore(parent);\n\t\tthis._position = position;\n\t\treturn this._formatReturnValue(\"elementStart\", parent, previousPosition, position, 1);\n\t}\n\t/**\n\t* Format returned data and adjust `previousPosition` and `nextPosition` if\n\t* reach the bound of the {@link module:engine/view/text~ViewText}.\n\t*\n\t* @param type Type of step.\n\t* @param item Item between old and new position.\n\t* @param previousPosition Previous position of iterator.\n\t* @param nextPosition Next position of iterator.\n\t* @param length Length of the item.\n\t*/\n\t_formatReturnValue(type, item, previousPosition, nextPosition, length) {\n\t\tif (item.is(\"view:$textProxy\")) {\n\t\t\tif (item.offsetInText + item.data.length == item.textNode.data.length) if (this.direction == \"forward\" && !(this.boundaries && this.boundaries.end.isEqual(this.position))) {\n\t\t\t\tnextPosition = ViewPosition._createAfter(item.textNode);\n\t\t\t\tthis._position = nextPosition;\n\t\t\t} else previousPosition = ViewPosition._createAfter(item.textNode);\n\t\t\tif (item.offsetInText === 0) if (this.direction == \"backward\" && !(this.boundaries && this.boundaries.start.isEqual(this.position))) {\n\t\t\t\tnextPosition = ViewPosition._createBefore(item.textNode);\n\t\t\t\tthis._position = nextPosition;\n\t\t\t} else previousPosition = ViewPosition._createBefore(item.textNode);\n\t\t}\n\t\treturn {\n\t\t\tdone: false,\n\t\t\tvalue: {\n\t\t\t\ttype,\n\t\t\t\titem,\n\t\t\t\tpreviousPosition,\n\t\t\t\tnextPosition,\n\t\t\t\tlength\n\t\t\t}\n\t\t};\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/position\n*/\n/**\n* Position in the view tree. Position is represented by its parent node and an offset in this parent.\n*\n* In order to create a new position instance use the `createPosition*()` factory methods available in:\n*\n* * {@link module:engine/view/view~EditingView}\n* * {@link module:engine/view/downcastwriter~ViewDowncastWriter}\n* * {@link module:engine/view/upcastwriter~ViewUpcastWriter}\n*/\nvar ViewPosition = class ViewPosition extends ViewTypeCheckable {\n\t/**\n\t* Position parent.\n\t*/\n\tparent;\n\t/**\n\t* Position offset.\n\t*/\n\toffset;\n\t/**\n\t* Creates a position.\n\t*\n\t* @param parent Position parent.\n\t* @param offset Position offset.\n\t*/\n\tconstructor(parent, offset) {\n\t\tsuper();\n\t\tthis.parent = parent;\n\t\tthis.offset = offset;\n\t}\n\t/**\n\t* Node directly after the position. Equals `null` when there is no node after position or position is located\n\t* inside text node.\n\t*/\n\tget nodeAfter() {\n\t\tif (this.parent.is(\"$text\")) return null;\n\t\treturn this.parent.getChild(this.offset) || null;\n\t}\n\t/**\n\t* Node directly before the position. Equals `null` when there is no node before position or position is located\n\t* inside text node.\n\t*/\n\tget nodeBefore() {\n\t\tif (this.parent.is(\"$text\")) return null;\n\t\treturn this.parent.getChild(this.offset - 1) || null;\n\t}\n\t/**\n\t* Is `true` if position is at the beginning of its {@link module:engine/view/position~ViewPosition#parent parent}, `false` otherwise.\n\t*/\n\tget isAtStart() {\n\t\treturn this.offset === 0;\n\t}\n\t/**\n\t* Is `true` if position is at the end of its {@link module:engine/view/position~ViewPosition#parent parent}, `false` otherwise.\n\t*/\n\tget isAtEnd() {\n\t\tconst endOffset = this.parent.is(\"$text\") ? this.parent.data.length : this.parent.childCount;\n\t\treturn this.offset === endOffset;\n\t}\n\t/**\n\t* Position's root, that is the root of the position's parent element.\n\t*/\n\tget root() {\n\t\treturn this.parent.root;\n\t}\n\t/**\n\t* {@link module:engine/view/editableelement~ViewEditableElement ViewEditableElement} instance that contains this position, or `null` if\n\t* position is not inside an editable element.\n\t*/\n\tget editableElement() {\n\t\tlet editable = this.parent;\n\t\twhile (!(editable instanceof ViewEditableElement)) if (editable.parent) editable = editable.parent;\n\t\telse return null;\n\t\treturn editable;\n\t}\n\t/**\n\t* Returns a new instance of Position with offset incremented by `shift` value.\n\t*\n\t* @param shift How position offset should get changed. Accepts negative values.\n\t* @returns Shifted position.\n\t*/\n\tgetShiftedBy(shift) {\n\t\tconst shifted = ViewPosition._createAt(this);\n\t\tconst offset = shifted.offset + shift;\n\t\tshifted.offset = offset < 0 ? 0 : offset;\n\t\treturn shifted;\n\t}\n\t/**\n\t* Gets the farthest position which matches the callback using\n\t* {@link module:engine/view/treewalker~ViewTreeWalker TreeWalker}.\n\t*\n\t* For example:\n\t*\n\t* ```ts\n\t* getLastMatchingPosition( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t* getLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } ); // <p>foo[]</p> -> <p>{}foo</p>\n\t* getLastMatchingPosition( value => false ); // Do not move the position.\n\t* ```\n\t*\n\t* @param skip Callback function. Gets {@link module:engine/view/treewalker~ViewTreeWalkerValue} and should\n\t* return `true` if the value should be skipped or `false` if not.\n\t* @param options Object with configuration options. See {@link module:engine/view/treewalker~ViewTreeWalker}.\n\t* @returns The position after the last item which matches the `skip` callback test.\n\t*/\n\tgetLastMatchingPosition(skip, options = {}) {\n\t\toptions.startPosition = this;\n\t\tconst treeWalker = new ViewTreeWalker(options);\n\t\ttreeWalker.skip(skip);\n\t\treturn treeWalker.position;\n\t}\n\t/**\n\t* Returns ancestors array of this position, that is this position's parent and it's ancestors.\n\t*\n\t* @returns Array with ancestors.\n\t*/\n\tgetAncestors() {\n\t\tif (this.parent.is(\"documentFragment\")) return [this.parent];\n\t\telse return this.parent.getAncestors({ includeSelf: true });\n\t}\n\t/**\n\t* Returns a {@link module:engine/view/node~ViewNode} or {@link module:engine/view/documentfragment~ViewDocumentFragment}\n\t* which is a common ancestor of both positions.\n\t*/\n\tgetCommonAncestor(position) {\n\t\tconst ancestorsA = this.getAncestors();\n\t\tconst ancestorsB = position.getAncestors();\n\t\tlet i = 0;\n\t\twhile (ancestorsA[i] == ancestorsB[i] && ancestorsA[i]) i++;\n\t\treturn i === 0 ? null : ancestorsA[i - 1];\n\t}\n\t/**\n\t* Checks whether this position equals given position.\n\t*\n\t* @param otherPosition Position to compare with.\n\t* @returns True if positions are same.\n\t*/\n\tisEqual(otherPosition) {\n\t\treturn this.parent == otherPosition.parent && this.offset == otherPosition.offset;\n\t}\n\t/**\n\t* Checks whether this position is located before given position. When method returns `false` it does not mean that\n\t* this position is after give one. Two positions may be located inside separate roots and in that situation this\n\t* method will still return `false`.\n\t*\n\t* @see module:engine/view/position~ViewPosition#isAfter\n\t* @see module:engine/view/position~ViewPosition#compareWith\n\t* @param otherPosition Position to compare with.\n\t* @returns Returns `true` if this position is before given position.\n\t*/\n\tisBefore(otherPosition) {\n\t\treturn this.compareWith(otherPosition) == \"before\";\n\t}\n\t/**\n\t* Checks whether this position is located after given position. When method returns `false` it does not mean that\n\t* this position is before give one. Two positions may be located inside separate roots and in that situation this\n\t* method will still return `false`.\n\t*\n\t* @see module:engine/view/position~ViewPosition#isBefore\n\t* @see module:engine/view/position~ViewPosition#compareWith\n\t* @param otherPosition Position to compare with.\n\t* @returns Returns `true` if this position is after given position.\n\t*/\n\tisAfter(otherPosition) {\n\t\treturn this.compareWith(otherPosition) == \"after\";\n\t}\n\t/**\n\t* Checks whether this position is before, after or in same position that other position. Two positions may be also\n\t* different when they are located in separate roots.\n\t*\n\t* @param otherPosition Position to compare with.\n\t*/\n\tcompareWith(otherPosition) {\n\t\tif (this.root !== otherPosition.root) return \"different\";\n\t\tif (this.isEqual(otherPosition)) return \"same\";\n\t\tconst thisPath = this.parent.is(\"node\") ? this.parent.getPath() : [];\n\t\tconst otherPath = otherPosition.parent.is(\"node\") ? otherPosition.parent.getPath() : [];\n\t\tthisPath.push(this.offset);\n\t\totherPath.push(otherPosition.offset);\n\t\tconst result = compareArrays(thisPath, otherPath);\n\t\tswitch (result) {\n\t\t\tcase \"prefix\": return \"before\";\n\t\t\tcase \"extension\": return \"after\";\n\t\t\tdefault: return thisPath[result] < otherPath[result] ? \"before\" : \"after\";\n\t\t}\n\t}\n\t/**\n\t* Creates a {@link module:engine/view/treewalker~ViewTreeWalker TreeWalker} instance with this positions as a start position.\n\t*\n\t* @param options Object with configuration options. See {@link module:engine/view/treewalker~ViewTreeWalker}\n\t*/\n\tgetWalker(options = {}) {\n\t\toptions.startPosition = this;\n\t\treturn new ViewTreeWalker(options);\n\t}\n\t/**\n\t* Clones this position.\n\t*/\n\tclone() {\n\t\treturn new ViewPosition(this.parent, this.offset);\n\t}\n\t/**\n\t* Converts `ViewPosition` instance to plain object and returns it.\n\t*\n\t* @returns `ViewPosition` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\treturn {\n\t\t\tparent: this.parent.toJSON(),\n\t\t\toffset: this.offset\n\t\t};\n\t}\n\t/**\n\t* Creates position at the given location. The location can be specified as:\n\t*\n\t* * a {@link module:engine/view/position~ViewPosition position},\n\t* * parent element and offset (offset defaults to `0`),\n\t* * parent element and `'end'` (sets position at the end of that element),\n\t* * {@link module:engine/view/item~ViewItem view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t*\n\t* This method is a shortcut to other constructors such as:\n\t*\n\t* * {@link module:engine/view/position~ViewPosition._createBefore},\n\t* * {@link module:engine/view/position~ViewPosition._createAfter}.\n\t*\n\t* @internal\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~ViewItem view item}.\n\t*/\n\tstatic _createAt(itemOrPosition, offset) {\n\t\tif (itemOrPosition instanceof ViewPosition) return new this(itemOrPosition.parent, itemOrPosition.offset);\n\t\telse {\n\t\t\tconst node = itemOrPosition;\n\t\t\tif (offset == \"end\") offset = node.is(\"$text\") ? node.data.length : node.childCount;\n\t\t\telse if (offset == \"before\") return this._createBefore(node);\n\t\t\telse if (offset == \"after\") return this._createAfter(node);\n\t\t\telse if (offset !== 0 && !offset)\n /**\n\t\t\t* {@link module:engine/view/view~EditingView#createPositionAt `View#createPositionAt()`}\n\t\t\t* requires the offset to be specified when the first parameter is a view item.\n\t\t\t*\n\t\t\t* @error view-createpositionat-offset-required\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"view-createpositionat-offset-required\", node);\n\t\t\treturn new ViewPosition(node, offset);\n\t\t}\n\t}\n\t/**\n\t* Creates a new position after given view item.\n\t*\n\t* @internal\n\t* @param item View item after which the position should be located.\n\t*/\n\tstatic _createAfter(item) {\n\t\tif (item.is(\"$textProxy\")) return new ViewPosition(item.textNode, item.offsetInText + item.data.length);\n\t\tif (!item.parent)\n /**\n\t\t* You cannot make a position after a root.\n\t\t*\n\t\t* @error view-position-after-root\n\t\t* @param {module:engine/view/node~ViewNode} root A root item.\n\t\t*/\n\t\tthrow new CKEditorError(\"view-position-after-root\", item, { root: item });\n\t\treturn new ViewPosition(item.parent, item.index + 1);\n\t}\n\t/**\n\t* Creates a new position before given view item.\n\t*\n\t* @internal\n\t* @param item View item before which the position should be located.\n\t*/\n\tstatic _createBefore(item) {\n\t\tif (item.is(\"$textProxy\")) return new ViewPosition(item.textNode, item.offsetInText);\n\t\tif (!item.parent)\n /**\n\t\t* You cannot make a position before a root.\n\t\t*\n\t\t* @error view-position-before-root\n\t\t* @param {module:engine/view/node~ViewNode} root A root item.\n\t\t*/\n\t\tthrow new CKEditorError(\"view-position-before-root\", item, { root: item });\n\t\treturn new ViewPosition(item.parent, item.index);\n\t}\n};\nViewPosition.prototype.is = function(type) {\n\treturn type === \"position\" || type === \"view:position\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/range\n*/\n/**\n* Range in the view tree. A range is represented by its start and end {@link module:engine/view/position~ViewPosition positions}.\n*\n* In order to create a new position instance use the `createPosition*()` factory methods available in:\n*\n* * {@link module:engine/view/view~EditingView}\n* * {@link module:engine/view/downcastwriter~ViewDowncastWriter}\n* * {@link module:engine/view/upcastwriter~ViewUpcastWriter}\n*/\nvar ViewRange = class ViewRange extends ViewTypeCheckable {\n\t/**\n\t* Start position.\n\t*/\n\tstart;\n\t/**\n\t* End position.\n\t*/\n\tend;\n\t/**\n\t* Creates a range spanning from `start` position to `end` position.\n\t*\n\t* **Note:** Constructor creates it's own {@link module:engine/view/position~ViewPosition} instances basing on passed values.\n\t*\n\t* @param start Start position.\n\t* @param end End position. If not set, range will be collapsed at the `start` position.\n\t*/\n\tconstructor(start, end = null) {\n\t\tsuper();\n\t\tthis.start = start.clone();\n\t\tthis.end = end ? end.clone() : start.clone();\n\t}\n\t/**\n\t* Iterable interface.\n\t*\n\t* Iterates over all {@link module:engine/view/item~ViewItem view items} that are in this range and returns\n\t* them together with additional information like length or {@link module:engine/view/position~ViewPosition positions},\n\t* grouped as {@link module:engine/view/treewalker~ViewTreeWalkerValue}.\n\t*\n\t* This iterator uses {@link module:engine/view/treewalker~ViewTreeWalker TreeWalker} with `boundaries` set to this range and\n\t* `ignoreElementEnd` option\n\t* set to `true`.\n\t*/\n\t*[Symbol.iterator]() {\n\t\tyield* new ViewTreeWalker({\n\t\t\tboundaries: this,\n\t\t\tignoreElementEnd: true\n\t\t});\n\t}\n\t/**\n\t* Returns whether the range is collapsed, that is it start and end positions are equal.\n\t*/\n\tget isCollapsed() {\n\t\treturn this.start.isEqual(this.end);\n\t}\n\t/**\n\t* Returns whether this range is flat, that is if {@link module:engine/view/range~ViewRange#start start} position and\n\t* {@link module:engine/view/range~ViewRange#end end} position are in the same\n\t* {@link module:engine/view/position~ViewPosition#parent parent}.\n\t*/\n\tget isFlat() {\n\t\treturn this.start.parent === this.end.parent;\n\t}\n\t/**\n\t* Range root element.\n\t*/\n\tget root() {\n\t\treturn this.start.root;\n\t}\n\t/**\n\t* Creates a maximal range that has the same content as this range but is expanded in both ways (at the beginning\n\t* and at the end).\n\t*\n\t* For example:\n\t*\n\t* ```html\n\t* <p>Foo</p><p><b>{Bar}</b></p> -> <p>Foo</p>[<p><b>Bar</b>]</p>\n\t* <p><b>foo</b>{bar}<span></span></p> -> <p><b>foo[</b>bar<span></span>]</p>\n\t* ```\n\t*\n\t* Note that in the sample above:\n\t*\n\t* - `<p>` have type of {@link module:engine/view/containerelement~ViewContainerElement},\n\t* - `<b>` have type of {@link module:engine/view/attributeelement~ViewAttributeElement},\n\t* - `<span>` have type of {@link module:engine/view/uielement~ViewUIElement}.\n\t*\n\t* @returns Enlarged range.\n\t*/\n\tgetEnlarged() {\n\t\tlet start = this.start.getLastMatchingPosition(enlargeTrimSkip, { direction: \"backward\" });\n\t\tlet end = this.end.getLastMatchingPosition(enlargeTrimSkip);\n\t\tif (start.parent.is(\"$text\") && start.isAtStart) start = ViewPosition._createBefore(start.parent);\n\t\tif (end.parent.is(\"$text\") && end.isAtEnd) end = ViewPosition._createAfter(end.parent);\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Creates a minimum range that has the same content as this range but is trimmed in both ways (at the beginning\n\t* and at the end).\n\t*\n\t* For example:\n\t*\n\t* ```html\n\t* <p>Foo</p>[<p><b>Bar</b>]</p> -> <p>Foo</p><p><b>{Bar}</b></p>\n\t* <p><b>foo[</b>bar<span></span>]</p> -> <p><b>foo</b>{bar}<span></span></p>\n\t* ```\n\t*\n\t* Note that in the sample above:\n\t*\n\t* - `<p>` have type of {@link module:engine/view/containerelement~ViewContainerElement},\n\t* - `<b>` have type of {@link module:engine/view/attributeelement~ViewAttributeElement},\n\t* - `<span>` have type of {@link module:engine/view/uielement~ViewUIElement}.\n\t*\n\t* @returns Shrunk range.\n\t*/\n\tgetTrimmed() {\n\t\tlet start = this.start.getLastMatchingPosition(enlargeTrimSkip);\n\t\tif (start.isAfter(this.end) || start.isEqual(this.end)) return new ViewRange(start, start);\n\t\tlet end = this.end.getLastMatchingPosition(enlargeTrimSkip, { direction: \"backward\" });\n\t\tconst nodeAfterStart = start.nodeAfter;\n\t\tconst nodeBeforeEnd = end.nodeBefore;\n\t\tif (nodeAfterStart && nodeAfterStart.is(\"$text\")) start = new ViewPosition(nodeAfterStart, 0);\n\t\tif (nodeBeforeEnd && nodeBeforeEnd.is(\"$text\")) end = new ViewPosition(nodeBeforeEnd, nodeBeforeEnd.data.length);\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Two ranges are equal if their start and end positions are equal.\n\t*\n\t* @param otherRange Range to compare with.\n\t* @returns `true` if ranges are equal, `false` otherwise\n\t*/\n\tisEqual(otherRange) {\n\t\treturn this == otherRange || this.start.isEqual(otherRange.start) && this.end.isEqual(otherRange.end);\n\t}\n\t/**\n\t* Checks whether this range contains given {@link module:engine/view/position~ViewPosition position}.\n\t*\n\t* @param position Position to check.\n\t* @returns `true` if given {@link module:engine/view/position~ViewPosition position} is contained in this range, `false` otherwise.\n\t*/\n\tcontainsPosition(position) {\n\t\treturn position.isAfter(this.start) && position.isBefore(this.end);\n\t}\n\t/**\n\t* Checks whether this range contains given {@link module:engine/view/range~ViewRange range}.\n\t*\n\t* @param otherRange Range to check.\n\t* @param loose Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n\t* start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n\t* even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n\t* @returns `true` if given {@link module:engine/view/range~ViewRange range} boundaries are contained by this range, `false`\n\t* otherwise.\n\t*/\n\tcontainsRange(otherRange, loose = false) {\n\t\tif (otherRange.isCollapsed) loose = false;\n\t\tconst containsStart = this.containsPosition(otherRange.start) || loose && this.start.isEqual(otherRange.start);\n\t\tconst containsEnd = this.containsPosition(otherRange.end) || loose && this.end.isEqual(otherRange.end);\n\t\treturn containsStart && containsEnd;\n\t}\n\t/**\n\t* Computes which part(s) of this {@link module:engine/view/range~ViewRange range} is not a part of given\n\t* {@link module:engine/view/range~ViewRange range}.\n\t* Returned array contains zero, one or two {@link module:engine/view/range~ViewRange ranges}.\n\t*\n\t* Examples:\n\t*\n\t* ```ts\n\t* let foo = downcastWriter.createText( 'foo' );\n\t* let img = downcastWriter.createContainerElement( 'img' );\n\t* let bar = downcastWriter.createText( 'bar' );\n\t* let p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n\t*\n\t* let range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t* let otherRange = view.createRange( // \"oo\", img, \"ba\" are in range.\n\t* \tview.createPositionAt( foo, 1 ),\n\t* \tview.createPositionAt( bar, 2 )\n\t* );\n\t* let transformed = range.getDifference( otherRange );\n\t* // transformed array has no ranges because `otherRange` contains `range`\n\t*\n\t* otherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n\t* transformed = range.getDifference( otherRange );\n\t* // transformed array has one range: from ( p, 2 ) to ( bar, 1 )\n\t*\n\t* otherRange = view.createRange( view.createPositionAt( p, 1 ), view.createPositionAt( p, 2 ) ); // img is in range.\n\t* transformed = range.getDifference( otherRange );\n\t* // transformed array has two ranges: from ( foo, 1 ) to ( p, 1 ) and from ( p, 2 ) to ( bar, 1 )\n\t* ```\n\t*\n\t* @param otherRange Range to differentiate against.\n\t* @returns The difference between ranges.\n\t*/\n\tgetDifference(otherRange) {\n\t\tconst ranges = [];\n\t\tif (this.isIntersecting(otherRange)) {\n\t\t\tif (this.containsPosition(otherRange.start)) ranges.push(new ViewRange(this.start, otherRange.start));\n\t\t\tif (this.containsPosition(otherRange.end)) ranges.push(new ViewRange(otherRange.end, this.end));\n\t\t} else ranges.push(this.clone());\n\t\treturn ranges;\n\t}\n\t/**\n\t* Returns an intersection of this {@link module:engine/view/range~ViewRange range}\n\t* and given {@link module:engine/view/range~ViewRange range}.\n\t* Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n\t*\n\t* Examples:\n\t*\n\t* ```ts\n\t* let foo = downcastWriter.createText( 'foo' );\n\t* let img = downcastWriter.createContainerElement( 'img' );\n\t* let bar = downcastWriter.createText( 'bar' );\n\t* let p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n\t*\n\t* let range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t* let otherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n\t* let transformed = range.getIntersection( otherRange ); // range from ( foo, 1 ) to ( p, 2 ).\n\t*\n\t* otherRange = view.createRange( view.createPositionAt( bar, 1 ), view.createPositionAt( bar, 3 ); \"ar\" is in range.\n\t* transformed = range.getIntersection( otherRange ); // null - no common part.\n\t* ```\n\t*\n\t* @param otherRange Range to check for intersection.\n\t* @returns A common part of given ranges or `null` if ranges have no common part.\n\t*/\n\tgetIntersection(otherRange) {\n\t\tif (this.isIntersecting(otherRange)) {\n\t\t\tlet commonRangeStart = this.start;\n\t\t\tlet commonRangeEnd = this.end;\n\t\t\tif (this.containsPosition(otherRange.start)) commonRangeStart = otherRange.start;\n\t\t\tif (this.containsPosition(otherRange.end)) commonRangeEnd = otherRange.end;\n\t\t\treturn new ViewRange(commonRangeStart, commonRangeEnd);\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Creates a {@link module:engine/view/treewalker~ViewTreeWalker TreeWalker} instance with this range as a boundary.\n\t*\n\t* @param options Object with configuration options. See {@link module:engine/view/treewalker~ViewTreeWalker}.\n\t*/\n\tgetWalker(options = {}) {\n\t\toptions.boundaries = this;\n\t\treturn new ViewTreeWalker(options);\n\t}\n\t/**\n\t* Returns a {@link module:engine/view/node~ViewNode} or {@link module:engine/view/documentfragment~ViewDocumentFragment}\n\t* which is a common ancestor of range's both ends (in which the entire range is contained).\n\t*/\n\tgetCommonAncestor() {\n\t\treturn this.start.getCommonAncestor(this.end);\n\t}\n\t/**\n\t* Returns an {@link module:engine/view/element~ViewElement Element} contained by the range.\n\t* The element will be returned when it is the **only** node within the range and **fully–contained**\n\t* at the same time.\n\t*/\n\tgetContainedElement() {\n\t\tif (this.isCollapsed) return null;\n\t\tlet nodeAfterStart = this.start.nodeAfter;\n\t\tlet nodeBeforeEnd = this.end.nodeBefore;\n\t\tif (this.start.parent.is(\"$text\") && this.start.isAtEnd && this.start.parent.nextSibling) nodeAfterStart = this.start.parent.nextSibling;\n\t\tif (this.end.parent.is(\"$text\") && this.end.isAtStart && this.end.parent.previousSibling) nodeBeforeEnd = this.end.parent.previousSibling;\n\t\tif (nodeAfterStart && nodeAfterStart.is(\"element\") && nodeAfterStart === nodeBeforeEnd) return nodeAfterStart;\n\t\treturn null;\n\t}\n\t/**\n\t* Clones this range.\n\t*/\n\tclone() {\n\t\treturn new ViewRange(this.start, this.end);\n\t}\n\t/**\n\t* Returns an iterator that iterates over all {@link module:engine/view/item~ViewItem view items} that are in this range and returns\n\t* them.\n\t*\n\t* This method uses {@link module:engine/view/treewalker~ViewTreeWalker} with `boundaries` set to this range\n\t* and `ignoreElementEnd` option set to `true`. However it returns only {@link module:engine/view/item~ViewItem items},\n\t* not {@link module:engine/view/treewalker~ViewTreeWalkerValue}.\n\t*\n\t* You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~ViewTreeWalker} for\n\t* a full list of available options.\n\t*\n\t* @param options Object with configuration options. See {@link module:engine/view/treewalker~ViewTreeWalker}.\n\t*/\n\t*getItems(options = {}) {\n\t\toptions.boundaries = this;\n\t\toptions.ignoreElementEnd = true;\n\t\tconst treeWalker = new ViewTreeWalker(options);\n\t\tfor (const value of treeWalker) yield value.item;\n\t}\n\t/**\n\t* Returns an iterator that iterates over all {@link module:engine/view/position~ViewPosition positions} that are boundaries or\n\t* contained in this range.\n\t*\n\t* This method uses {@link module:engine/view/treewalker~ViewTreeWalker} with `boundaries` set to this range. However it returns only\n\t* {@link module:engine/view/position~ViewPosition positions}, not {@link module:engine/view/treewalker~ViewTreeWalkerValue}.\n\t*\n\t* You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~ViewTreeWalker} for\n\t* a full list of available options.\n\t*\n\t* @param options Object with configuration options. See {@link module:engine/view/treewalker~ViewTreeWalker}.\n\t*/\n\t*getPositions(options = {}) {\n\t\toptions.boundaries = this;\n\t\tconst treeWalker = new ViewTreeWalker(options);\n\t\tyield treeWalker.position;\n\t\tfor (const value of treeWalker) yield value.nextPosition;\n\t}\n\t/**\n\t* Checks and returns whether this range intersects with the given range.\n\t*\n\t* @param otherRange Range to compare with.\n\t* @returns True if ranges intersect.\n\t*/\n\tisIntersecting(otherRange) {\n\t\treturn this.start.isBefore(otherRange.end) && this.end.isAfter(otherRange.start);\n\t}\n\t/**\n\t* Converts `ViewRange` instance to plain object and returns it.\n\t*\n\t* @returns `ViewRange` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\treturn {\n\t\t\tstart: this.start.toJSON(),\n\t\t\tend: this.end.toJSON()\n\t\t};\n\t}\n\t/**\n\t* Creates a range from the given parents and offsets.\n\t*\n\t* @internal\n\t* @param startElement Start position parent element.\n\t* @param startOffset Start position offset.\n\t* @param endElement End position parent element.\n\t* @param endOffset End position offset.\n\t* @returns Created range.\n\t*/\n\tstatic _createFromParentsAndOffsets(startElement, startOffset, endElement, endOffset) {\n\t\treturn new this(new ViewPosition(startElement, startOffset), new ViewPosition(endElement, endOffset));\n\t}\n\t/**\n\t* Creates a new range, spreading from specified {@link module:engine/view/position~ViewPosition position} to a position moved by\n\t* given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n\t*\n\t* @internal\n\t* @param position Beginning of the range.\n\t* @param shift How long the range should be.\n\t*/\n\tstatic _createFromPositionAndShift(position, shift) {\n\t\tconst start = position;\n\t\tconst end = position.getShiftedBy(shift);\n\t\treturn shift > 0 ? new this(start, end) : new this(end, start);\n\t}\n\t/**\n\t* Creates a range inside an {@link module:engine/view/element~ViewElement element} which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* @internal\n\t* @param element Element which is a parent for the range.\n\t*/\n\tstatic _createIn(element) {\n\t\treturn this._createFromParentsAndOffsets(element, 0, element, element.childCount);\n\t}\n\t/**\n\t* Creates a range that starts before given {@link module:engine/view/item~ViewItem view item} and ends after it.\n\t*\n\t* @internal\n\t*/\n\tstatic _createOn(item) {\n\t\tconst size = item.is(\"$textProxy\") ? item.offsetSize : 1;\n\t\treturn this._createFromPositionAndShift(ViewPosition._createBefore(item), size);\n\t}\n};\nViewRange.prototype.is = function(type) {\n\treturn type === \"range\" || type === \"view:range\";\n};\n/**\n* Function used by getEnlarged and getTrimmed methods.\n*/\nfunction enlargeTrimSkip(value) {\n\tif (value.item.is(\"attributeElement\") || value.item.is(\"uiElement\")) return true;\n\treturn false;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/selection\n*/\nconst ViewSelectionBase = /* #__PURE__ */ EmitterMixin(ViewTypeCheckable);\n/**\n* Class representing an arbirtary selection in the view.\n* See also {@link module:engine/view/documentselection~ViewDocumentSelection}.\n*\n* New selection instances can be created via the constructor or one these methods:\n*\n* * {@link module:engine/view/view~EditingView#createSelection `View#createSelection()`},\n* * {@link module:engine/view/upcastwriter~ViewUpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n*\n* A selection can consist of {@link module:engine/view/range~ViewRange ranges} that can be set by using\n* the {@link module:engine/view/selection~ViewSelection#setTo `Selection#setTo()`} method.\n*/\nvar ViewSelection = class ViewSelection extends ViewSelectionBase {\n\t/**\n\t* Stores all ranges that are selected.\n\t*/\n\t_ranges;\n\t/**\n\t* Specifies whether the last added range was added as a backward or forward range.\n\t*/\n\t_lastRangeBackward;\n\t/**\n\t* Specifies whether selection instance is fake.\n\t*/\n\t_isFake;\n\t/**\n\t* Fake selection's label.\n\t*/\n\t_fakeSelectionLabel;\n\t/**\n\t* Creates new selection instance.\n\t*\n\t* **Note**: The selection constructor is available as a factory method:\n\t*\n\t* * {@link module:engine/view/view~EditingView#createSelection `View#createSelection()`},\n\t* * {@link module:engine/view/upcastwriter~ViewUpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n\t*\n\t* ```ts\n\t* // Creates empty selection without ranges.\n\t* const selection = writer.createSelection();\n\t*\n\t* // Creates selection at the given range.\n\t* const range = writer.createRange( start, end );\n\t* const selection = writer.createSelection( range );\n\t*\n\t* // Creates selection at the given ranges\n\t* const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t* const selection = writer.createSelection( ranges );\n\t*\n\t* // Creates selection from the other selection.\n\t* const otherSelection = writer.createSelection();\n\t* const selection = writer.createSelection( otherSelection );\n\t*\n\t* // Creates selection from the document selection.\n\t* const selection = writer.createSelection( editor.editing.view.document.selection );\n\t*\n\t* // Creates selection at the given position.\n\t* const position = writer.createPositionFromPath( root, path );\n\t* const selection = writer.createSelection( position );\n\t*\n\t* // Creates collapsed selection at the position of given item and offset.\n\t* const paragraph = writer.createContainerElement( 'paragraph' );\n\t* const selection = writer.createSelection( paragraph, offset );\n\t*\n\t* // Creates a range inside an {@link module:engine/view/element~ViewElement element} which starts before the\n\t* // first child of that element and ends after the last child of that element.\n\t* const selection = writer.createSelection( paragraph, 'in' );\n\t*\n\t* // Creates a range on an {@link module:engine/view/item~ViewItem item} which starts before the item and ends\n\t* // just after the item.\n\t* const selection = writer.createSelection( paragraph, 'on' );\n\t* ```\n\t*\n\t* `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t*\n\t* ```ts\n\t* // Creates backward selection.\n\t* const selection = writer.createSelection( range, { backward: true } );\n\t* ```\n\t*\n\t* Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t* This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t* represented in other way, for example by applying proper CSS class.\n\t*\n\t* Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t* (and be properly handled by screen readers).\n\t*\n\t* ```ts\n\t* // Creates fake selection with label.\n\t* const selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t* ```\n\t*\n\t* @internal\n\t*/\n\tconstructor(...args) {\n\t\tsuper();\n\t\tthis._ranges = [];\n\t\tthis._lastRangeBackward = false;\n\t\tthis._isFake = false;\n\t\tthis._fakeSelectionLabel = \"\";\n\t\tif (args.length) this.setTo(...args);\n\t}\n\t/**\n\t* Returns true if selection instance is marked as `fake`.\n\t*\n\t* @see #setTo\n\t*/\n\tget isFake() {\n\t\treturn this._isFake;\n\t}\n\t/**\n\t* Returns fake selection label.\n\t*\n\t* @see #setTo\n\t*/\n\tget fakeSelectionLabel() {\n\t\treturn this._fakeSelectionLabel;\n\t}\n\t/**\n\t* Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t* {@link #focus focus} they define the direction of selection, which is important\n\t* when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t* It may be a bit unintuitive when there are multiple ranges in selection.\n\t*\n\t* @see #focus\n\t*/\n\tget anchor() {\n\t\tif (!this._ranges.length) return null;\n\t\tconst range = this._ranges[this._ranges.length - 1];\n\t\treturn (this._lastRangeBackward ? range.end : range.start).clone();\n\t}\n\t/**\n\t* Selection focus. Focus is a position where the selection ends.\n\t*\n\t* @see #anchor\n\t*/\n\tget focus() {\n\t\tif (!this._ranges.length) return null;\n\t\tconst range = this._ranges[this._ranges.length - 1];\n\t\treturn (this._lastRangeBackward ? range.start : range.end).clone();\n\t}\n\t/**\n\t* Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t* collapsed.\n\t*/\n\tget isCollapsed() {\n\t\treturn this.rangeCount === 1 && this._ranges[0].isCollapsed;\n\t}\n\t/**\n\t* Returns number of ranges in selection.\n\t*/\n\tget rangeCount() {\n\t\treturn this._ranges.length;\n\t}\n\t/**\n\t* Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t*/\n\tget isBackward() {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\t/**\n\t* {@link module:engine/view/editableelement~ViewEditableElement ViewEditableElement} instance that contains this selection, or `null`\n\t* if the selection is not inside an editable element.\n\t*/\n\tget editableElement() {\n\t\tif (this.anchor) return this.anchor.editableElement;\n\t\treturn null;\n\t}\n\t/**\n\t* Returns an iterable that contains copies of all ranges added to the selection.\n\t*/\n\t*getRanges() {\n\t\tfor (const range of this._ranges) yield range.clone();\n\t}\n\t/**\n\t* Returns copy of the first range in the selection. First range is the one which\n\t* {@link module:engine/view/range~ViewRange#start start} position\n\t* {@link module:engine/view/position~ViewPosition#isBefore is before} start\n\t* position of all other ranges (not to confuse with the first range added to the selection).\n\t* Returns `null` if no ranges are added to selection.\n\t*/\n\tgetFirstRange() {\n\t\tlet first = null;\n\t\tfor (const range of this._ranges) if (!first || range.start.isBefore(first.start)) first = range;\n\t\treturn first ? first.clone() : null;\n\t}\n\t/**\n\t* Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~ViewRange#end end}\n\t* position {@link module:engine/view/position~ViewPosition#isAfter is after} end position of all other ranges (not to confuse\n\t* with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t*/\n\tgetLastRange() {\n\t\tlet last = null;\n\t\tfor (const range of this._ranges) if (!last || range.end.isAfter(last.end)) last = range;\n\t\treturn last ? last.clone() : null;\n\t}\n\t/**\n\t* Returns copy of the first position in the selection. First position is the position that\n\t* {@link module:engine/view/position~ViewPosition#isBefore is before} any other position in the selection ranges.\n\t* Returns `null` if no ranges are added to selection.\n\t*/\n\tgetFirstPosition() {\n\t\tconst firstRange = this.getFirstRange();\n\t\treturn firstRange ? firstRange.start.clone() : null;\n\t}\n\t/**\n\t* Returns copy of the last position in the selection. Last position is the position that\n\t* {@link module:engine/view/position~ViewPosition#isAfter is after} any other position in the selection ranges.\n\t* Returns `null` if no ranges are added to selection.\n\t*/\n\tgetLastPosition() {\n\t\tconst lastRange = this.getLastRange();\n\t\treturn lastRange ? lastRange.end.clone() : null;\n\t}\n\t/**\n\t* Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t* same number of ranges and all ranges from one selection equal to a range from other selection.\n\t*\n\t* @param otherSelection Selection to compare with.\n\t* @returns `true` if selections are equal, `false` otherwise.\n\t*/\n\tisEqual(otherSelection) {\n\t\tif (this.isFake != otherSelection.isFake) return false;\n\t\tif (this.isFake && this.fakeSelectionLabel != otherSelection.fakeSelectionLabel) return false;\n\t\tif (this.rangeCount != otherSelection.rangeCount) return false;\n\t\telse if (this.rangeCount === 0) return true;\n\t\tif (!this.anchor.isEqual(otherSelection.anchor) || !this.focus.isEqual(otherSelection.focus)) return false;\n\t\tfor (const thisRange of this._ranges) {\n\t\t\tlet found = false;\n\t\t\tfor (const otherRange of otherSelection._ranges) if (thisRange.isEqual(otherRange)) {\n\t\t\t\tfound = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!found) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t* number of ranges, and all {@link module:engine/view/range~ViewRange#getTrimmed trimmed} ranges from one selection are\n\t* equal to any trimmed range from other selection.\n\t*\n\t* @param otherSelection Selection to compare with.\n\t* @returns `true` if selections are similar, `false` otherwise.\n\t*/\n\tisSimilar(otherSelection) {\n\t\tif (this.isBackward != otherSelection.isBackward) return false;\n\t\tconst numOfRangesA = count(this.getRanges());\n\t\tif (numOfRangesA != count(otherSelection.getRanges())) return false;\n\t\tif (numOfRangesA == 0) return true;\n\t\tfor (let rangeA of this.getRanges()) {\n\t\t\trangeA = rangeA.getTrimmed();\n\t\t\tlet found = false;\n\t\t\tfor (let rangeB of otherSelection.getRanges()) {\n\t\t\t\trangeB = rangeB.getTrimmed();\n\t\t\t\tif (rangeA.start.isEqual(rangeB.start) && rangeA.end.isEqual(rangeB.end)) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Returns the selected element. {@link module:engine/view/element~ViewElement Element} is considered as selected if there is only\n\t* one range in the selection, and that range contains exactly one element.\n\t* Returns `null` if there is no selected element.\n\t*/\n\tgetSelectedElement() {\n\t\tif (this.rangeCount !== 1) return null;\n\t\treturn this.getFirstRange().getContainedElement();\n\t}\n\t/**\n\t* Sets this selection's ranges and direction to the specified location based on the given\n\t* {@link module:engine/view/selection~ViewSelectable selectable}.\n\t*\n\t* ```ts\n\t* // Sets selection to the given range.\n\t* const range = writer.createRange( start, end );\n\t* selection.setTo( range );\n\t*\n\t* // Sets selection to given ranges.\n\t* const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t* selection.setTo( range );\n\t*\n\t* // Sets selection to the other selection.\n\t* const otherSelection = writer.createSelection();\n\t* selection.setTo( otherSelection );\n\t*\n\t* // Sets selection to contents of ViewDocumentSelection.\n\t* selection.setTo( editor.editing.view.document.selection );\n\t*\n\t* // Sets collapsed selection at the given position.\n\t* const position = writer.createPositionAt( root, path );\n\t* selection.setTo( position );\n\t*\n\t* // Sets collapsed selection at the position of given item and offset.\n\t* selection.setTo( paragraph, offset );\n\t* ```\n\t*\n\t* Creates a range inside an {@link module:engine/view/element~ViewElement element} which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* ```ts\n\t* selection.setTo( paragraph, 'in' );\n\t* ```\n\t*\n\t* Creates a range on an {@link module:engine/view/item~ViewItem item} which starts before the item and ends just after the item.\n\t*\n\t* ```ts\n\t* selection.setTo( paragraph, 'on' );\n\t*\n\t* // Clears selection. Removes all ranges.\n\t* selection.setTo( null );\n\t* ```\n\t*\n\t* `Selection#setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t*\n\t* ```ts\n\t* // Sets selection as backward.\n\t* selection.setTo( range, { backward: true } );\n\t* ```\n\t*\n\t* Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t* This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t* represented in other way, for example by applying proper CSS class.\n\t*\n\t* Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t* (and be properly handled by screen readers).\n\t*\n\t* ```ts\n\t* // Creates fake selection with label.\n\t* selection.setTo( range, { fake: true, label: 'foo' } );\n\t* ```\n\t*\n\t* @fires change\n\t*/\n\tsetTo(...args) {\n\t\tlet [selectable, placeOrOffset, options] = args;\n\t\tif (typeof placeOrOffset == \"object\") {\n\t\t\toptions = placeOrOffset;\n\t\t\tplaceOrOffset = void 0;\n\t\t}\n\t\tif (selectable === null) {\n\t\t\tthis._setRanges([]);\n\t\t\tthis._setFakeOptions(options);\n\t\t} else if (selectable instanceof ViewSelection || selectable instanceof ViewDocumentSelection) {\n\t\t\tthis._setRanges(selectable.getRanges(), selectable.isBackward);\n\t\t\tthis._setFakeOptions({\n\t\t\t\tfake: selectable.isFake,\n\t\t\t\tlabel: selectable.fakeSelectionLabel\n\t\t\t});\n\t\t} else if (selectable instanceof ViewRange) {\n\t\t\tthis._setRanges([selectable], options && options.backward);\n\t\t\tthis._setFakeOptions(options);\n\t\t} else if (selectable instanceof ViewPosition) {\n\t\t\tthis._setRanges([new ViewRange(selectable)]);\n\t\t\tthis._setFakeOptions(options);\n\t\t} else if (selectable instanceof ViewNode) {\n\t\t\tconst backward = !!options && !!options.backward;\n\t\t\tlet range;\n\t\t\tif (placeOrOffset === void 0)\n /**\n\t\t\t* selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t*\n\t\t\t* @error view-selection-setto-required-second-parameter\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"view-selection-setto-required-second-parameter\", this);\n\t\t\telse if (placeOrOffset == \"in\") range = ViewRange._createIn(selectable);\n\t\t\telse if (placeOrOffset == \"on\") range = ViewRange._createOn(selectable);\n\t\t\telse range = new ViewRange(ViewPosition._createAt(selectable, placeOrOffset));\n\t\t\tthis._setRanges([range], backward);\n\t\t\tthis._setFakeOptions(options);\n\t\t} else if (isIterable(selectable)) {\n\t\t\tthis._setRanges(selectable, options && options.backward);\n\t\t\tthis._setFakeOptions(options);\n\t\t} else\n /**\n\t\t* Cannot set selection to given place.\n\t\t*\n\t\t* @error view-selection-setto-not-selectable\n\t\t*/\n\t\tthrow new CKEditorError(\"view-selection-setto-not-selectable\", this);\n\t\tthis.fire(\"change\");\n\t}\n\t/**\n\t* Moves {@link #focus} to the specified location.\n\t*\n\t* The location can be specified in the same form as\n\t* {@link module:engine/view/view~EditingView#createPositionAt view.createPositionAt()}\n\t* parameters.\n\t*\n\t* @fires change\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~ViewItem view item}.\n\t*/\n\tsetFocus(itemOrPosition, offset) {\n\t\tif (this.anchor === null)\n /**\n\t\t* Cannot set selection focus if there are no ranges in selection.\n\t\t*\n\t\t* @error view-selection-setfocus-no-ranges\n\t\t*/\n\t\tthrow new CKEditorError(\"view-selection-setfocus-no-ranges\", this);\n\t\tconst newFocus = ViewPosition._createAt(itemOrPosition, offset);\n\t\tif (newFocus.compareWith(this.focus) == \"same\") return;\n\t\tconst anchor = this.anchor;\n\t\tthis._ranges.pop();\n\t\tif (newFocus.compareWith(anchor) == \"before\") this._addRange(new ViewRange(newFocus, anchor), true);\n\t\telse this._addRange(new ViewRange(anchor, newFocus));\n\t\tthis.fire(\"change\");\n\t}\n\t/**\n\t* Converts `ViewSelection` instance to plain object and returns it.\n\t*\n\t* @returns `ViewSelection` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = { ranges: Array.from(this.getRanges()).map((range) => range.toJSON()) };\n\t\tif (this.isBackward) json.isBackward = true;\n\t\tif (this.isFake) json.isFake = true;\n\t\treturn json;\n\t}\n\t/**\n\t* Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t* is treated like the last added range and is used to set {@link #anchor anchor} and {@link #focus focus}.\n\t* Accepts a flag describing in which way the selection is made.\n\t*\n\t* @param newRanges Iterable object of ranges to set.\n\t* @param isLastBackward Flag describing if last added range was selected forward - from start to end\n\t* (`false`) or backward - from end to start (`true`). Defaults to `false`.\n\t*/\n\t_setRanges(newRanges, isLastBackward = false) {\n\t\tnewRanges = Array.from(newRanges);\n\t\tthis._ranges = [];\n\t\tfor (const range of newRanges) this._addRange(range);\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\t}\n\t/**\n\t* Sets this selection instance to be marked as `fake`. A fake selection does not render as browser native selection\n\t* over selected elements and is hidden to the user. This way, no native selection UI artifacts are displayed to\n\t* the user and selection over elements can be represented in other way, for example by applying proper CSS class.\n\t*\n\t* Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM (and be\n\t* properly handled by screen readers).\n\t*/\n\t_setFakeOptions(options = {}) {\n\t\tthis._isFake = !!options.fake;\n\t\tthis._fakeSelectionLabel = options.fake ? options.label || \"\" : \"\";\n\t}\n\t/**\n\t* Adds a range to the selection. Added range is copied. This means that passed range is not saved in the\n\t* selection instance and you can safely operate on it.\n\t*\n\t* Accepts a flag describing in which way the selection is made - passed range might be selected from\n\t* {@link module:engine/view/range~ViewRange#start start} to {@link module:engine/view/range~ViewRange#end end}\n\t* or from {@link module:engine/view/range~ViewRange#end end} to {@link module:engine/view/range~ViewRange#start start}.\n\t* The flag is used to set {@link #anchor anchor} and {@link #focus focus} properties.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t* with ranges already stored in Selection instance.\n\t*/\n\t_addRange(range, isBackward = false) {\n\t\tif (!(range instanceof ViewRange))\n /**\n\t\t* Selection range set to an object that is not an instance of {@link module:engine/view/range~ViewRange}.\n\t\t*\n\t\t* @error view-selection-add-range-not-range\n\t\t*/\n\t\tthrow new CKEditorError(\"view-selection-add-range-not-range\", this);\n\t\tthis._pushRange(range);\n\t\tthis._lastRangeBackward = !!isBackward;\n\t}\n\t/**\n\t* Adds range to selection - creates copy of given range so it can be safely used and modified.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t* with ranges already stored in selection instance.\n\t*/\n\t_pushRange(range) {\n\t\tfor (const storedRange of this._ranges) if (range.isIntersecting(storedRange))\n /**\n\t\t* Trying to add a range that intersects with another range from selection.\n\t\t*\n\t\t* @error view-selection-range-intersects\n\t\t* @param {module:engine/view/range~ViewRange} addedRange Range that was added to the selection.\n\t\t* @param {module:engine/view/range~ViewRange} intersectingRange Range from selection that intersects with `addedRange`.\n\t\t*/\n\t\tthrow new CKEditorError(\"view-selection-range-intersects\", this, {\n\t\t\taddedRange: range,\n\t\t\tintersectingRange: storedRange\n\t\t});\n\t\tthis._ranges.push(new ViewRange(range.start, range.end));\n\t}\n};\nViewSelection.prototype.is = function(type) {\n\treturn type === \"selection\" || type === \"view:selection\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/documentselection\n*/\nconst ViewDocumentSelectionBase = /* #__PURE__ */ EmitterMixin(ViewTypeCheckable);\n/**\n* Class representing the document selection in the view.\n*\n* Its instance is available in {@link module:engine/view/document~ViewDocument#selection `Document#selection`}.\n*\n* It is similar to {@link module:engine/view/selection~ViewSelection} but\n* it has a read-only API and can be modified only by the writer available in\n* the {@link module:engine/view/view~EditingView#change `View#change()`} block\n* (so via {@link module:engine/view/downcastwriter~ViewDowncastWriter#setSelection `ViewDowncastWriter#setSelection()`}).\n*/\nvar ViewDocumentSelection = class extends ViewDocumentSelectionBase {\n\t/**\n\t* Selection is used internally (`ViewDocumentSelection` is a proxy to that selection).\n\t*/\n\t_selection;\n\tconstructor(...args) {\n\t\tsuper();\n\t\tthis._selection = new ViewSelection();\n\t\tthis._selection.delegate(\"change\").to(this);\n\t\tif (args.length) this._selection.setTo(...args);\n\t}\n\t/**\n\t* Returns true if selection instance is marked as `fake`.\n\t*\n\t* @see #_setTo\n\t*/\n\tget isFake() {\n\t\treturn this._selection.isFake;\n\t}\n\t/**\n\t* Returns fake selection label.\n\t*\n\t* @see #_setTo\n\t*/\n\tget fakeSelectionLabel() {\n\t\treturn this._selection.fakeSelectionLabel;\n\t}\n\t/**\n\t* Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t* {@link #focus focus} they define the direction of selection, which is important\n\t* when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t* It may be a bit unintuitive when there are multiple ranges in selection.\n\t*\n\t* @see #focus\n\t*/\n\tget anchor() {\n\t\treturn this._selection.anchor;\n\t}\n\t/**\n\t* Selection focus. Focus is a position where the selection ends.\n\t*\n\t* @see #anchor\n\t*/\n\tget focus() {\n\t\treturn this._selection.focus;\n\t}\n\t/**\n\t* Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t* collapsed.\n\t*/\n\tget isCollapsed() {\n\t\treturn this._selection.isCollapsed;\n\t}\n\t/**\n\t* Returns number of ranges in selection.\n\t*/\n\tget rangeCount() {\n\t\treturn this._selection.rangeCount;\n\t}\n\t/**\n\t* Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t*/\n\tget isBackward() {\n\t\treturn this._selection.isBackward;\n\t}\n\t/**\n\t* {@link module:engine/view/editableelement~ViewEditableElement ViewEditableElement} instance that contains this selection, or `null`\n\t* if the selection is not inside an editable element.\n\t*/\n\tget editableElement() {\n\t\treturn this._selection.editableElement;\n\t}\n\t/**\n\t* Used for the compatibility with the {@link module:engine/view/selection~ViewSelection#isEqual} method.\n\t*\n\t* @internal\n\t*/\n\tget _ranges() {\n\t\treturn this._selection._ranges;\n\t}\n\t/**\n\t* Returns an iterable that contains copies of all ranges added to the selection.\n\t*/\n\t*getRanges() {\n\t\tyield* this._selection.getRanges();\n\t}\n\t/**\n\t* Returns copy of the first range in the selection. First range is the one which\n\t* {@link module:engine/view/range~ViewRange#start start} position\n\t* {@link module:engine/view/position~ViewPosition#isBefore is before} start\n\t* position of all other ranges (not to confuse with the first range added to the selection).\n\t* Returns `null` if no ranges are added to selection.\n\t*/\n\tgetFirstRange() {\n\t\treturn this._selection.getFirstRange();\n\t}\n\t/**\n\t* Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~ViewRange#end end}\n\t* position {@link module:engine/view/position~ViewPosition#isAfter is after} end position of all other ranges (not to confuse\n\t* with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t*/\n\tgetLastRange() {\n\t\treturn this._selection.getLastRange();\n\t}\n\t/**\n\t* Returns copy of the first position in the selection. First position is the position that\n\t* {@link module:engine/view/position~ViewPosition#isBefore is before} any other position in the selection ranges.\n\t* Returns `null` if no ranges are added to selection.\n\t*/\n\tgetFirstPosition() {\n\t\treturn this._selection.getFirstPosition();\n\t}\n\t/**\n\t* Returns copy of the last position in the selection. Last position is the position that\n\t* {@link module:engine/view/position~ViewPosition#isAfter is after} any other position in the selection ranges.\n\t* Returns `null` if no ranges are added to selection.\n\t*/\n\tgetLastPosition() {\n\t\treturn this._selection.getLastPosition();\n\t}\n\t/**\n\t* Returns the selected element. {@link module:engine/view/element~ViewElement Element} is considered as selected if there is only\n\t* one range in the selection, and that range contains exactly one element.\n\t* Returns `null` if there is no selected element.\n\t*/\n\tgetSelectedElement() {\n\t\treturn this._selection.getSelectedElement();\n\t}\n\t/**\n\t* Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t* same number of ranges and all ranges from one selection equal to a range from other selection.\n\t*\n\t* @param otherSelection Selection to compare with.\n\t* @returns `true` if selections are equal, `false` otherwise.\n\t*/\n\tisEqual(otherSelection) {\n\t\treturn this._selection.isEqual(otherSelection);\n\t}\n\t/**\n\t* Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t* number of ranges, and all {@link module:engine/view/range~ViewRange#getTrimmed trimmed} ranges from one selection are\n\t* equal to any trimmed range from other selection.\n\t*\n\t* @param otherSelection Selection to compare with.\n\t* @returns `true` if selections are similar, `false` otherwise.\n\t*/\n\tisSimilar(otherSelection) {\n\t\treturn this._selection.isSimilar(otherSelection);\n\t}\n\t/**\n\t* Converts `ViewDocumentSelection` instance to plain object and returns it.\n\t*\n\t* @returns `ViewDocumentSelection` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\treturn this._selection.toJSON();\n\t}\n\t/**\n\t* Sets this selection's ranges and direction to the specified location based on the given\n\t* {@link module:engine/view/selection~ViewSelectable selectable}.\n\t*\n\t* ```ts\n\t* // Sets selection to the given range.\n\t* const range = writer.createRange( start, end );\n\t* documentSelection._setTo( range );\n\t*\n\t* // Sets selection to given ranges.\n\t* const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];\n\t* documentSelection._setTo( range );\n\t*\n\t* // Sets selection to the other selection.\n\t* const otherSelection = writer.createSelection();\n\t* documentSelection._setTo( otherSelection );\n\t*\n\t* // Sets collapsed selection at the given position.\n\t* const position = writer.createPositionAt( root, offset );\n\t* documentSelection._setTo( position );\n\t*\n\t* // Sets collapsed selection at the position of given item and offset.\n\t* documentSelection._setTo( paragraph, offset );\n\t* ```\n\t*\n\t* Creates a range inside an {@link module:engine/view/element~ViewElement element} which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* ```ts\n\t* documentSelection._setTo( paragraph, 'in' );\n\t* ```\n\t*\n\t* Creates a range on an {@link module:engine/view/item~ViewItem item} which starts before the item and ends just after the item.\n\t*\n\t* ```ts\n\t* documentSelection._setTo( paragraph, 'on' );\n\t*\n\t* // Clears selection. Removes all ranges.\n\t* documentSelection._setTo( null );\n\t* ```\n\t*\n\t* `Selection#_setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t*\n\t* ```ts\n\t* // Sets selection as backward.\n\t* documentSelection._setTo( range, { backward: true } );\n\t* ```\n\t*\n\t* Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t* This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t* represented in other way, for example by applying proper CSS class.\n\t*\n\t* Additionally fake's selection label can be provided. It will be used to des cribe fake selection in DOM\n\t* (and be properly handled by screen readers).\n\t*\n\t* ```ts\n\t* // Creates fake selection with label.\n\t* documentSelection._setTo( range, { fake: true, label: 'foo' } );\n\t* ```\n\t*\n\t* @internal\n\t* @fires change\n\t*/\n\t_setTo(...args) {\n\t\tthis._selection.setTo(...args);\n\t}\n\t/**\n\t* Moves {@link #focus} to the specified location.\n\t*\n\t* The location can be specified in the same form as\n\t* {@link module:engine/view/view~EditingView#createPositionAt view.createPositionAt()}\n\t* parameters.\n\t*\n\t* @internal\n\t* @fires change\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~ViewItem view item}.\n\t*/\n\t_setFocus(itemOrPosition, offset) {\n\t\tthis._selection.setFocus(itemOrPosition, offset);\n\t}\n};\nViewDocumentSelection.prototype.is = function(type) {\n\treturn type === \"selection\" || type == \"documentSelection\" || type == \"view:selection\" || type == \"view:documentSelection\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/bubblingeventinfo\n*/\n/**\n* The event object passed to bubbling event callbacks. It is used to provide information about the event as well as a tool to\n* manipulate it.\n*/\nvar BubblingEventInfo = class extends EventInfo {\n\t/**\n\t* The view range that the bubbling should start from.\n\t*/\n\tstartRange;\n\t/**\n\t* The current event phase.\n\t*/\n\t_eventPhase;\n\t/**\n\t* The current bubbling target.\n\t*/\n\t_currentTarget;\n\t/**\n\t* @param source The emitter.\n\t* @param name The event name.\n\t* @param startRange The view range that the bubbling should start from.\n\t*/\n\tconstructor(source, name, startRange) {\n\t\tsuper(source, name);\n\t\tthis.startRange = startRange;\n\t\tthis._eventPhase = \"none\";\n\t\tthis._currentTarget = null;\n\t}\n\t/**\n\t* The current event phase.\n\t*/\n\tget eventPhase() {\n\t\treturn this._eventPhase;\n\t}\n\t/**\n\t* The current bubbling target.\n\t*/\n\tget currentTarget() {\n\t\treturn this._currentTarget;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/bubblingemittermixin\n*/\nconst bubblingEmitterSymbol = Symbol(\"bubblingEmitter\");\nconst callbackMapSymbol = Symbol(\"bubblingCallbacks\");\nconst contextsSymbol = Symbol(\"bubblingContexts\");\n/**\n* Bubbling emitter mixin for the view document as described in the {@link ~BubblingEmitter} interface.\n*\n* This function creates a class that inherits from the provided `base` and implements `Emitter` interface.\n* The base class must implement {@link module:utils/emittermixin~Emitter} interface.\n*\n* ```ts\n* class BaseClass extends EmitterMixin() {\n* \t// ...\n* }\n*\n* class MyClass extends BubblingEmitterMixin( BaseClass ) {\n* \t// This class derives from `BaseClass` and implements the `BubblingEmitter` interface.\n* }\n* ```\n*/\nfunction BubblingEmitterMixin(base) {\n\tclass Mixin extends base {\n\t\tfire(eventOrInfo, ...eventArgs) {\n\t\t\ttry {\n\t\t\t\tconst eventInfo = eventOrInfo instanceof EventInfo ? eventOrInfo : new EventInfo(this, eventOrInfo);\n\t\t\t\tconst bubblingEmitter = getBubblingEmitter(this);\n\t\t\t\tconst customContexts = getCustomContexts(this);\n\t\t\t\tupdateEventInfo(eventInfo, \"capturing\", this);\n\t\t\t\tif (fireListenerFor(bubblingEmitter, \"$capture\", eventInfo, ...eventArgs)) return eventInfo.return;\n\t\t\t\tconst startRange = eventInfo.startRange || this.selection.getFirstRange();\n\t\t\t\tconst selectedElement = startRange ? startRange.getContainedElement() : null;\n\t\t\t\tconst isCustomContext = selectedElement ? hasMatchingCustomContext(customContexts, selectedElement) : false;\n\t\t\t\tlet node = selectedElement || getDeeperRangeParent(startRange);\n\t\t\t\tupdateEventInfo(eventInfo, \"atTarget\", node);\n\t\t\t\tif (!isCustomContext) {\n\t\t\t\t\tif (fireListenerFor(bubblingEmitter, \"$text\", eventInfo, ...eventArgs)) return eventInfo.return;\n\t\t\t\t\tupdateEventInfo(eventInfo, \"bubbling\", node);\n\t\t\t\t}\n\t\t\t\twhile (node) {\n\t\t\t\t\tif (node.is(\"element\") && fireListenerFor(bubblingEmitter, node, eventInfo, ...eventArgs)) return eventInfo.return;\n\t\t\t\t\tnode = node.parent;\n\t\t\t\t\tupdateEventInfo(eventInfo, \"bubbling\", node);\n\t\t\t\t}\n\t\t\t\tupdateEventInfo(eventInfo, \"bubbling\", this);\n\t\t\t\tfireListenerFor(bubblingEmitter, \"$document\", eventInfo, ...eventArgs);\n\t\t\t\treturn eventInfo.return;\n\t\t\t} catch (err) {\n\t\t\t\tCKEditorError.rethrowUnexpectedError(err, this);\n\t\t\t}\n\t\t}\n\t\t_addEventListener(event, callback, options) {\n\t\t\tconst contexts = toArray(options.context || \"$document\");\n\t\t\tconst bubblingEmitter = getBubblingEmitter(this);\n\t\t\tconst callbacksMap = getCallbackMap(this);\n\t\t\tfor (const context of contexts) if (typeof context == \"function\") getCustomContexts(this).add(context);\n\t\t\tconst wrappedCallback = wrapCallback(this, contexts, callback);\n\t\t\tcallbacksMap.set(callback, wrappedCallback);\n\t\t\tthis.listenTo(bubblingEmitter, event, wrappedCallback, options);\n\t\t}\n\t\t_removeEventListener(event, callback) {\n\t\t\tconst bubblingEmitter = getBubblingEmitter(this);\n\t\t\tconst callbacksMap = getCallbackMap(this);\n\t\t\tconst wrappedCallback = callbacksMap.get(callback);\n\t\t\tif (wrappedCallback) {\n\t\t\t\tcallbacksMap.delete(callback);\n\t\t\t\tthis.stopListening(bubblingEmitter, event, wrappedCallback);\n\t\t\t}\n\t\t}\n\t}\n\treturn Mixin;\n}\n/**\n* Update the event info bubbling fields.\n*\n* @param eventInfo The event info object to update.\n* @param eventPhase The current event phase.\n* @param currentTarget The current bubbling target.\n*/\nfunction updateEventInfo(eventInfo, eventPhase, currentTarget) {\n\tif (eventInfo instanceof BubblingEventInfo) {\n\t\teventInfo._eventPhase = eventPhase;\n\t\teventInfo._currentTarget = currentTarget;\n\t}\n}\n/**\n* Fires the listener for the specified context. Returns `true` if event was stopped.\n*\n* @param eventInfo The `EventInfo` object.\n* @param eventArgs Additional arguments to be passed to the callbacks.\n* @returns True if event stop was called.\n*/\nfunction fireListenerFor(emitter, currentTarget, eventInfo, ...eventArgs) {\n\temitter.fire(eventInfo, {\n\t\tcurrentTarget,\n\t\teventArgs\n\t});\n\tif (eventInfo.stop.called) return true;\n\treturn false;\n}\n/**\n* Returns an event callback wrapped with context check condition.\n*/\nfunction wrapCallback(emitter, contexts, callback) {\n\treturn function(event, data) {\n\t\tconst { currentTarget, eventArgs } = data;\n\t\tif (typeof currentTarget == \"string\") {\n\t\t\tif (contexts.includes(currentTarget)) callback.call(emitter, event, ...eventArgs);\n\t\t\treturn;\n\t\t}\n\t\tif (currentTarget.is(\"rootElement\") && contexts.includes(\"$root\")) {\n\t\t\tcallback.call(emitter, event, ...eventArgs);\n\t\t\treturn;\n\t\t}\n\t\tif (contexts.includes(currentTarget.name)) {\n\t\t\tcallback.call(emitter, event, ...eventArgs);\n\t\t\treturn;\n\t\t}\n\t\tfor (const context of contexts) if (typeof context == \"function\" && context(currentTarget)) {\n\t\t\tcallback.call(emitter, event, ...eventArgs);\n\t\t\treturn;\n\t\t}\n\t};\n}\n/**\n* Returns bubbling emitter for the source (emitter).\n*/\nfunction getBubblingEmitter(source) {\n\tif (!source[bubblingEmitterSymbol]) source[bubblingEmitterSymbol] = new (EmitterMixin())();\n\treturn source[bubblingEmitterSymbol];\n}\n/**\n* Returns map of callbacks (original to wrapped one).\n*/\nfunction getCallbackMap(source) {\n\tif (!source[callbackMapSymbol]) source[callbackMapSymbol] = /* @__PURE__ */ new Map();\n\treturn source[callbackMapSymbol];\n}\n/**\n* Returns the set of registered custom contexts.\n*/\nfunction getCustomContexts(source) {\n\tif (!source[contextsSymbol]) source[contextsSymbol] = /* @__PURE__ */ new Set();\n\treturn source[contextsSymbol];\n}\n/**\n* Returns true if any of custom context match the given element.\n*/\nfunction hasMatchingCustomContext(customContexts, element) {\n\tfor (const context of customContexts) if (context(element)) return true;\n\treturn false;\n}\n/**\n* Returns the deeper parent element for the range.\n*/\nfunction getDeeperRangeParent(range) {\n\tif (!range) return null;\n\tconst startParent = range.start.parent;\n\tconst endParent = range.end.parent;\n\tconst startPath = startParent.getPath();\n\tconst endPath = endParent.getPath();\n\treturn startPath.length > endPath.length ? startParent : endParent;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/document\n*/\nconst ViewDocumentBase = /* #__PURE__ */ BubblingEmitterMixin(/* #__PURE__ */ ObservableMixin());\n/**\n* Document class creates an abstract layer over the content editable area, contains a tree of view elements and\n* {@link module:engine/view/documentselection~ViewDocumentSelection view selection} associated with this document.\n*/\nvar ViewDocument = class extends ViewDocumentBase {\n\t/**\n\t* Selection done on this document.\n\t*/\n\tselection;\n\t/**\n\t* Roots of the view tree. Collection of the {@link module:engine/view/element~ViewElement view elements}.\n\t*\n\t* View roots are created as a result of binding between {@link module:engine/view/document~ViewDocument#roots} and\n\t* {@link module:engine/model/document~ModelDocument#roots} and this is handled by\n\t* {@link module:engine/controller/editingcontroller~EditingController}, so to create view root we need to create\n\t* model root using {@link module:engine/model/document~ModelDocument#createRoot}.\n\t*/\n\troots;\n\t/**\n\t* The styles processor instance used by this document when normalizing styles.\n\t*/\n\tstylesProcessor;\n\t/**\n\t* Post-fixer callbacks registered to the view document.\n\t*/\n\t_postFixers = /* @__PURE__ */ new Set();\n\t/**\n\t* Creates a Document instance.\n\t*\n\t* @param stylesProcessor The styles processor instance.\n\t*/\n\tconstructor(stylesProcessor) {\n\t\tsuper();\n\t\tthis.selection = new ViewDocumentSelection();\n\t\tthis.roots = new Collection({ idProperty: \"rootName\" });\n\t\tthis.stylesProcessor = stylesProcessor;\n\t\tthis.set(\"isReadOnly\", false);\n\t\tthis.set(\"isFocused\", false);\n\t\tthis.set(\"isSelecting\", false);\n\t\tthis.set(\"isComposing\", false);\n\t}\n\t/**\n\t* Gets a {@link module:engine/view/document~ViewDocument#roots view root element} with the specified name. If the name is not\n\t* specific \"main\" root is returned.\n\t*\n\t* @param name Name of the root.\n\t* @returns The view root element with the specified name or null when there is no root of given name.\n\t*/\n\tgetRoot(name = \"main\") {\n\t\treturn this.roots.get(name);\n\t}\n\t/**\n\t* Returns an array with all roots added to the document.\n\t*/\n\tgetRoots() {\n\t\treturn Array.from(this.roots);\n\t}\n\t/**\n\t* Allows registering post-fixer callbacks. A post-fixers mechanism allows to update the view tree just before it is rendered\n\t* to the DOM.\n\t*\n\t* Post-fixers are executed right after all changes from the outermost change block were applied but\n\t* before the {@link module:engine/view/view~EditingView#event:render render event} is fired. If a post-fixer callback made\n\t* a change, it should return `true`. When this happens, all post-fixers are fired again to check if something else should\n\t* not be fixed in the new document tree state.\n\t*\n\t* View post-fixers are useful when you want to apply some fixes whenever the view structure changes. Keep in mind that\n\t* changes executed in a view post-fixer should not break model-view mapping.\n\t*\n\t* The types of changes which should be safe:\n\t*\n\t* * adding or removing attribute from elements,\n\t* * changes inside of {@link module:engine/view/uielement~ViewUIElement UI elements},\n\t* * {@link module:engine/controller/editingcontroller~EditingController#reconvertItem marking some of the model elements to be\n\t* re-converted}.\n\t*\n\t* Try to avoid changes which touch view structure:\n\t*\n\t* * you should not add or remove nor wrap or unwrap any view elements,\n\t* * you should not change the editor data model in a view post-fixer.\n\t*\n\t* As a parameter, a post-fixer callback receives a {@link module:engine/view/downcastwriter~ViewDowncastWriter downcast writer}.\n\t*\n\t* Typically, a post-fixer will look like this:\n\t*\n\t* ```ts\n\t* editor.editing.view.document.registerPostFixer( writer => {\n\t* \tif ( checkSomeCondition() ) {\n\t* \t\twriter.doSomething();\n\t*\n\t* \t\t// Let other post-fixers know that something changed.\n\t* \t\treturn true;\n\t* \t}\n\t*\n\t* \treturn false;\n\t* } );\n\t* ```\n\t*\n\t* Note that nothing happens right after you register a post-fixer (e.g. execute such a code in the console).\n\t* That is because adding a post-fixer does not execute it.\n\t* The post-fixer will be executed as soon as any change in the document needs to cause its rendering.\n\t* If you want to re-render the editor's view after registering the post-fixer then you should do it manually by calling\n\t* {@link module:engine/view/view~EditingView#forceRender `view.forceRender()`}.\n\t*\n\t* If you need to register a callback which is executed when DOM elements are already updated,\n\t* use {@link module:engine/view/view~EditingView#event:render render event}.\n\t*/\n\tregisterPostFixer(postFixer) {\n\t\tthis._postFixers.add(postFixer);\n\t}\n\t/**\n\t* Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t*/\n\tdestroy() {\n\t\tthis.roots.forEach((root) => root.destroy());\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.\n\t*\n\t* @internal\n\t*/\n\t_callPostFixers(writer) {\n\t\tlet wasFixed = false;\n\t\tdo\n\t\t\tfor (const callback of this._postFixers) {\n\t\t\t\twasFixed = callback(writer);\n\t\t\t\tif (wasFixed) break;\n\t\t\t}\n\t\twhile (wasFixed);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/attributeelement\n*/\nconst DEFAULT_PRIORITY = 10;\n/**\n* Attribute elements are used to represent formatting elements in the view (think – `<b>`, `<span style=\"font-size: 2em\">`, etc.).\n* Most often they are created when downcasting model text attributes.\n*\n* Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various\n* types (container element, {@link module:engine/view/attributeelement~ViewAttributeElement attribute element},\n* {@link module:engine/view/emptyelement~ViewEmptyElement empty element}, etc) when developing a feature.\n*\n* To create a new attribute element instance use the\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createAttributeElement `ViewDowncastWriter#createAttributeElement()`} method.\n*/\nvar ViewAttributeElement = class extends ViewElement {\n\tstatic DEFAULT_PRIORITY = DEFAULT_PRIORITY;\n\t/**\n\t* Element priority. Decides in what order elements are wrapped by {@link module:engine/view/downcastwriter~ViewDowncastWriter}.\n\t*\n\t* @internal\n\t* @readonly\n\t*/\n\t_priority = DEFAULT_PRIORITY;\n\t/**\n\t* Element identifier. If set, it is used by {@link module:engine/view/element~ViewElement#isSimilar},\n\t* and then two elements are considered similar if, and only if they have the same `_id`.\n\t*\n\t* @internal\n\t* @readonly\n\t*/\n\t_id = null;\n\t/**\n\t* Keeps all the attribute elements that have the same {@link module:engine/view/attributeelement~ViewAttributeElement#id ids}\n\t* and still exist in the view tree.\n\t*\n\t* This property is managed by {@link module:engine/view/downcastwriter~ViewDowncastWriter}.\n\t*/\n\t_clonesGroup = null;\n\t/**\n\t* Creates an attribute element.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#createAttributeElement\n\t* @see module:engine/view/element~ViewElement\n\t* @protected\n\t* @param document The document instance to which this element belongs.\n\t* @param name Node name.\n\t* @param attrs Collection of attributes.\n\t* @param children A list of nodes to be inserted into created element.\n\t*/\n\tconstructor(document, name, attrs, children) {\n\t\tsuper(document, name, attrs, children);\n\t\tthis.getFillerOffset = getFillerOffset$3;\n\t}\n\t/**\n\t* Element priority. Decides in what order elements are wrapped by {@link module:engine/view/downcastwriter~ViewDowncastWriter}.\n\t*/\n\tget priority() {\n\t\treturn this._priority;\n\t}\n\t/**\n\t* Element identifier. If set, it is used by {@link module:engine/view/element~ViewElement#isSimilar},\n\t* and then two elements are considered similar if, and only if they have the same `id`.\n\t*/\n\tget id() {\n\t\treturn this._id;\n\t}\n\t/**\n\t* Returns all {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements} that has the\n\t* same {@link module:engine/view/attributeelement~ViewAttributeElement#id id} and are in the view tree (were not removed).\n\t*\n\t* Note: If this element has been removed from the tree, returned set will not include it.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError attribute-element-get-elements-with-same-id-no-id}\n\t* if this element has no `id`.\n\t*\n\t* @returns Set containing all the attribute elements\n\t* with the same `id` that were added and not removed from the view tree.\n\t*/\n\tgetElementsWithSameId() {\n\t\tif (this.id === null)\n /**\n\t\t* Cannot get elements with the same id for an attribute element without id.\n\t\t*\n\t\t* @error attribute-element-get-elements-with-same-id-no-id\n\t\t*/\n\t\tthrow new CKEditorError(\"attribute-element-get-elements-with-same-id-no-id\", this);\n\t\treturn new Set(this._clonesGroup);\n\t}\n\t/**\n\t* Checks if this element is similar to other element.\n\t*\n\t* If none of elements has set {@link module:engine/view/attributeelement~ViewAttributeElement#id}, then both elements\n\t* should have the same name, attributes and priority to be considered as similar. Two similar elements can contain\n\t* different set of children nodes.\n\t*\n\t* If at least one element has {@link module:engine/view/attributeelement~ViewAttributeElement#id} set, then both\n\t* elements have to have the same {@link module:engine/view/attributeelement~ViewAttributeElement#id} value to be\n\t* considered similar.\n\t*\n\t* Similarity is important for {@link module:engine/view/downcastwriter~ViewDowncastWriter}. For example:\n\t*\n\t* * two following similar elements can be merged together into one, longer element,\n\t* * {@link module:engine/view/downcastwriter~ViewDowncastWriter#unwrap} checks similarity of passed element and processed element to\n\t* decide whether processed element should be unwrapped,\n\t* * etc.\n\t*/\n\tisSimilar(otherElement) {\n\t\tif (this.id !== null || otherElement.id !== null) return this.id === otherElement.id;\n\t\treturn super.isSimilar(otherElement) && this.priority == otherElement.priority;\n\t}\n\t/**\n\t* Converts `ViewAttributeElement` instance to plain object and returns it.\n\t*\n\t* @returns `ViewAttributeElement` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.type = \"AttributeElement\";\n\t\treturn json;\n\t}\n\t/**\n\t* Clones provided element with priority.\n\t*\n\t* @internal\n\t* @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t* element will be cloned without any children.\n\t* @returns Clone of this element.\n\t*/\n\t_clone(deep = false) {\n\t\tconst cloned = super._clone(deep);\n\t\tcloned._priority = this._priority;\n\t\tcloned._id = this._id;\n\t\treturn cloned;\n\t}\n\t/**\n\t* Used by {@link module:engine/view/element~ViewElement#_mergeAttributesFrom} to verify if the given element can be merged without\n\t* conflicts into this element.\n\t*\n\t* @internal\n\t*/\n\t_canMergeAttributesFrom(otherElement) {\n\t\tif (this.id !== null || otherElement.id !== null || this.priority !== otherElement.priority) return false;\n\t\treturn super._canMergeAttributesFrom(otherElement);\n\t}\n\t/**\n\t* Used by {@link module:engine/view/element~ViewElement#_subtractAttributesOf} to verify if the given element attributes\n\t* can be fully subtracted from this element.\n\t*\n\t* @internal\n\t*/\n\t_canSubtractAttributesOf(otherElement) {\n\t\tif (this.id !== null || otherElement.id !== null || this.priority !== otherElement.priority) return false;\n\t\treturn super._canSubtractAttributesOf(otherElement);\n\t}\n};\nViewAttributeElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"attributeElement\" || type === \"view:attributeElement\" || type === \"element\" || type === \"view:element\" || type === \"node\" || type === \"view:node\";\n\telse return name === this.name && (type === \"attributeElement\" || type === \"view:attributeElement\" || type === \"element\" || type === \"view:element\");\n};\n/**\n* Returns block {@link module:engine/view/filler~Filler filler} offset or `null` if block filler is not needed.\n*\n* @returns Block filler offset or `null` if block filler is not needed.\n*/\nfunction getFillerOffset$3() {\n\tif (nonUiChildrenCount(this)) return null;\n\tlet element = this.parent;\n\twhile (element && element.is(\"attributeElement\")) {\n\t\tif (nonUiChildrenCount(element) > 1) return null;\n\t\telement = element.parent;\n\t}\n\tif (!element || nonUiChildrenCount(element) > 1) return null;\n\treturn this.childCount;\n}\n/**\n* Returns total count of children that are not {@link module:engine/view/uielement~ViewUIElement UIElements}.\n*/\nfunction nonUiChildrenCount(element) {\n\treturn Array.from(element.getChildren()).filter((element) => !element.is(\"uiElement\")).length;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/emptyelement\n*/\n/**\n* Empty element class. It is used to represent elements that cannot contain any child nodes (for example `<img>` elements).\n*\n* To create a new empty element use the\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`} method.\n*/\nvar ViewEmptyElement = class extends ViewElement {\n\t/**\n\t* Creates new instance of ViewEmptyElement.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` when third parameter is passed,\n\t* to inform that usage of ViewEmptyElement is incorrect (adding child nodes to ViewEmptyElement is forbidden).\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#createEmptyElement\n\t* @internal\n\t* @param document The document instance to which this element belongs.\n\t* @param name Node name.\n\t* @param attributes Collection of attributes.\n\t* @param children A list of nodes to be inserted into created element.\n\t*/\n\tconstructor(document, name, attributes, children) {\n\t\tsuper(document, name, attributes, children);\n\t\tthis.getFillerOffset = getFillerOffset$2;\n\t}\n\t/**\n\t* Converts `ViewEmptyElement` instance to plain object and returns it.\n\t*\n\t* @returns `ViewEmptyElement` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.type = \"EmptyElement\";\n\t\treturn json;\n\t}\n\t/**\n\t* Overrides {@link module:engine/view/element~ViewElement#_insertChild} method.\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` to prevent\n\t* adding any child nodes to ViewEmptyElement.\n\t*\n\t* @internal\n\t*/\n\t_insertChild(index, items) {\n\t\tif (items && (items instanceof ViewNode || Array.from(items).length > 0))\n /**\n\t\t* Cannot add children to {@link module:engine/view/emptyelement~ViewEmptyElement}.\n\t\t*\n\t\t* @error view-emptyelement-cannot-add\n\t\t*/\n\t\tthrow new CKEditorError(\"view-emptyelement-cannot-add\", [this, items]);\n\t\treturn 0;\n\t}\n};\nViewEmptyElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"emptyElement\" || type === \"view:emptyElement\" || type === \"element\" || type === \"view:element\" || type === \"node\" || type === \"view:node\";\n\telse return name === this.name && (type === \"emptyElement\" || type === \"view:emptyElement\" || type === \"element\" || type === \"view:element\");\n};\n/**\n* Returns `null` because block filler is not needed for ViewEmptyElements.\n*/\nfunction getFillerOffset$2() {\n\treturn null;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/uielement\n*/\n/**\n* UI element class. It should be used to represent editing UI which needs to be injected into the editing view\n* If possible, you should keep your UI outside the editing view. However, if that is not possible,\n* UI elements can be used.\n*\n* How a UI element is rendered is in your control (you pass a callback to\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createUIElement `downcastWriter#createUIElement()`}).\n* The editor will ignore your UI element – the selection cannot be placed in it, it is skipped (invisible) when\n* the user modifies the selection by using arrow keys and the editor does not listen to any mutations which\n* happen inside your UI elements.\n*\n* The limitation is that you cannot convert a model element to a UI element. UI elements need to be\n* created for {@link module:engine/model/markercollection~Marker markers} or as additinal elements\n* inside normal {@link module:engine/view/containerelement~ViewContainerElement container elements}.\n*\n* To create a new UI element use the\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createUIElement `downcastWriter#createUIElement()`} method.\n*/\nvar ViewUIElement = class extends ViewElement {\n\t/**\n\t* Creates new instance of UIElement.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` when third parameter is passed,\n\t* to inform that usage of UIElement is incorrect (adding child nodes to UIElement is forbidden).\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#createUIElement\n\t* @internal\n\t* @param document The document instance to which this element belongs.\n\t* @param name Node name.\n\t* @param attrs Collection of attributes.\n\t* @param children A list of nodes to be inserted into created element.\n\t*/\n\tconstructor(document, name, attrs, children) {\n\t\tsuper(document, name, attrs, children);\n\t\tthis.getFillerOffset = getFillerOffset$1;\n\t}\n\t/**\n\t* Overrides {@link module:engine/view/element~ViewElement#_insertChild} method.\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` to prevent adding any child nodes\n\t* to UIElement.\n\t*\n\t* @internal\n\t*/\n\t_insertChild(index, items) {\n\t\tif (items && (items instanceof ViewNode || Array.from(items).length > 0))\n /**\n\t\t* Cannot add children to {@link module:engine/view/uielement~ViewUIElement}.\n\t\t*\n\t\t* @error view-uielement-cannot-add\n\t\t*/\n\t\tthrow new CKEditorError(\"view-uielement-cannot-add\", [this, items]);\n\t\treturn 0;\n\t}\n\t/**\n\t* Renders this {@link module:engine/view/uielement~ViewUIElement} to DOM. This method is called by\n\t* {@link module:engine/view/domconverter~ViewDomConverter}.\n\t* Do not use inheritance to create custom rendering method, replace `render()` method instead:\n\t*\n\t* ```ts\n\t* const myUIElement = downcastWriter.createUIElement( 'span' );\n\t* myUIElement.render = function( domDocument, domConverter ) {\n\t* \tconst domElement = this.toDomElement( domDocument );\n\t*\n\t* \tdomConverter.setContentOf( domElement, '<b>this is ui element</b>' );\n\t*\n\t* \treturn domElement;\n\t* };\n\t* ```\n\t*\n\t* If changes in your UI element should trigger some editor UI update you should call\n\t* the {@link module:ui/editorui/editorui~EditorUI#update `editor.ui.update()`} method\n\t* after rendering your UI element.\n\t*\n\t* @param domConverter Instance of the ViewDomConverter used to optimize the output.\n\t*/\n\trender(domDocument, domConverter) {\n\t\treturn this.toDomElement(domDocument);\n\t}\n\t/**\n\t* Creates DOM element based on this view UIElement.\n\t* Note that each time this method is called new DOM element is created.\n\t*/\n\ttoDomElement(domDocument) {\n\t\tconst domElement = domDocument.createElement(this.name);\n\t\tfor (const key of this.getAttributeKeys()) domElement.setAttribute(key, this.getAttribute(key));\n\t\treturn domElement;\n\t}\n\t/**\n\t* Converts `ViewUIElement` instance to plain object and returns it.\n\t*\n\t* @returns `ViewUIElement` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.type = \"UIElement\";\n\t\treturn json;\n\t}\n};\nViewUIElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"uiElement\" || type === \"view:uiElement\" || type === \"element\" || type === \"view:element\" || type === \"node\" || type === \"view:node\";\n\telse return name === this.name && (type === \"uiElement\" || type === \"view:uiElement\" || type === \"element\" || type === \"view:element\");\n};\n/**\n* This function injects UI element handling to the given {@link module:engine/view/document~ViewDocument document}.\n*\n* A callback is added to {@link module:engine/view/document~ViewDocument#event:keydown document keydown event}.\n* The callback handles the situation when right arrow key is pressed and selection is collapsed before a UI element.\n* Without this handler, it would be impossible to \"jump over\" UI element using right arrow key.\n*\n* @param view View controller to which the quirks handling will be injected.\n* @internal\n*/\nfunction injectUiElementHandling(view) {\n\tview.document.on(\"arrowKey\", (evt, data) => jumpOverUiElement(evt, data, view.domConverter), { priority: \"low\" });\n}\n/**\n* Returns `null` because block filler is not needed for UIElements.\n*/\nfunction getFillerOffset$1() {\n\treturn null;\n}\n/**\n* Selection cannot be placed in a `UIElement`. Whenever it is placed there, it is moved before it. This\n* causes a situation when it is impossible to jump over `UIElement` using right arrow key, because the selection\n* ends up in ui element (in DOM) and is moved back to the left. This handler fixes this situation.\n*/\nfunction jumpOverUiElement(evt, data, domConverter) {\n\tif (data.keyCode == keyCodes.arrowright) {\n\t\tconst domSelection = data.domTarget.ownerDocument.defaultView.getSelection();\n\t\tconst domSelectionCollapsed = domSelection.rangeCount == 1 && domSelection.getRangeAt(0).collapsed;\n\t\tif (domSelectionCollapsed || data.shiftKey) {\n\t\t\tconst domParent = domSelection.focusNode;\n\t\t\tconst domOffset = domSelection.focusOffset;\n\t\t\tconst viewPosition = domConverter.domPositionToView(domParent, domOffset);\n\t\t\tif (viewPosition === null) return;\n\t\t\tlet jumpedOverAnyUiElement = false;\n\t\t\tconst nextViewPosition = viewPosition.getLastMatchingPosition((value) => {\n\t\t\t\tif (value.item.is(\"uiElement\")) jumpedOverAnyUiElement = true;\n\t\t\t\tif (value.item.is(\"uiElement\") || value.item.is(\"attributeElement\")) return true;\n\t\t\t\treturn false;\n\t\t\t});\n\t\t\tif (jumpedOverAnyUiElement) {\n\t\t\t\tconst newDomPosition = domConverter.viewPositionToDom(nextViewPosition);\n\t\t\t\tif (domSelectionCollapsed) domSelection.collapse(newDomPosition.parent, newDomPosition.offset);\n\t\t\t\telse domSelection.extend(newDomPosition.parent, newDomPosition.offset);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/rawelement\n*/\n/**\n* The raw element class.\n*\n* The raw elements work as data containers (\"wrappers\", \"sandboxes\") but their children are not managed or\n* even recognized by the editor. This encapsulation allows integrations to maintain custom DOM structures\n* in the editor content without, for instance, worrying about compatibility with other editor features.\n* Raw elements are a perfect tool for integration with external frameworks and data sources.\n*\n* Unlike {@link module:engine/view/uielement~ViewUIElement UI elements}, raw elements act like real editor\n* content (similar to {@link module:engine/view/containerelement~ViewContainerElement} or\n* {@link module:engine/view/emptyelement~ViewEmptyElement}), they are considered by the editor selection and\n* {@link module:widget/utils~toWidget they can work as widgets}.\n*\n* To create a new raw element, use the\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createRawElement `downcastWriter#createRawElement()`} method.\n*/\nvar ViewRawElement = class extends ViewElement {\n\t/**\n\t* Creates a new instance of a raw element.\n\t*\n\t* Throws the `view-rawelement-cannot-add` {@link module:utils/ckeditorerror~CKEditorError CKEditorError} when the `children`\n\t* parameter is passed to inform that the usage of `ViewRawElement` is incorrect (adding child nodes to `ViewRawElement` is forbidden).\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#createRawElement\n\t* @internal\n\t* @param document The document instance to which this element belongs.\n\t* @param name Node name.\n\t* @param attrs Collection of attributes.\n\t* @param children A list of nodes to be inserted into created element.\n\t*/\n\tconstructor(document, name, attrs, children) {\n\t\tsuper(document, name, attrs, children);\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\t/**\n\t* Converts `ViewRawElement` instance to plain object and returns it.\n\t*\n\t* @returns `ViewRawElement` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.type = \"RawElement\";\n\t\treturn json;\n\t}\n\t/**\n\t* Overrides the {@link module:engine/view/element~ViewElement#_insertChild} method.\n\t* Throws the `view-rawelement-cannot-add` {@link module:utils/ckeditorerror~CKEditorError CKEditorError} to prevent\n\t* adding any child nodes to a raw element.\n\t*\n\t* @internal\n\t*/\n\t_insertChild(index, items) {\n\t\tif (items && (items instanceof ViewNode || Array.from(items).length > 0))\n /**\n\t\t* Cannot add children to a {@link module:engine/view/rawelement~ViewRawElement} instance.\n\t\t*\n\t\t* @error view-rawelement-cannot-add\n\t\t*/\n\t\tthrow new CKEditorError(\"view-rawelement-cannot-add\", [this, items]);\n\t\treturn 0;\n\t}\n\t/**\n\t* This allows rendering the children of a {@link module:engine/view/rawelement~ViewRawElement} on the DOM level.\n\t* This method is called by the {@link module:engine/view/domconverter~ViewDomConverter} with the raw DOM element\n\t* passed as an argument, leaving the number and shape of the children up to the integrator.\n\t*\n\t* This method **must be defined** for the raw element to work:\n\t*\n\t* ```ts\n\t* const myRawElement = downcastWriter.createRawElement( 'div' );\n\t*\n\t* myRawElement.render = function( domElement, domConverter ) {\n\t* \tdomConverter.setContentOf( domElement, '<b>This is the raw content of myRawElement.</b>' );\n\t* };\n\t* ```\n\t*\n\t* @param domElement The native DOM element representing the raw view element.\n\t* @param domConverter Instance of the ViewDomConverter used to optimize the output.\n\t*/\n\trender(domElement, domConverter) {}\n};\nViewRawElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"rawElement\" || type === \"view:rawElement\" || type === this.name || type === \"view:\" + this.name || type === \"element\" || type === \"view:element\" || type === \"node\" || type === \"view:node\";\n\telse return name === this.name && (type === \"rawElement\" || type === \"view:rawElement\" || type === \"element\" || type === \"view:element\");\n};\n/**\n* Returns `null` because block filler is not needed for raw elements.\n*/\nfunction getFillerOffset() {\n\treturn null;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/documentfragment\n*/\nconst ViewDocumentFragmentBase = /* #__PURE__ */ EmitterMixin(ViewTypeCheckable);\n/**\n* Document fragment.\n*\n* To create a new document fragment instance use the\n* {@link module:engine/view/upcastwriter~ViewUpcastWriter#createDocumentFragment `ViewUpcastWriter#createDocumentFragment()`}\n* method.\n*/\nvar ViewDocumentFragment = class extends ViewDocumentFragmentBase {\n\t/**\n\t* The document to which this document fragment belongs.\n\t*/\n\tdocument;\n\t/**\n\t* Array of child nodes.\n\t*/\n\t_children = [];\n\t/**\n\t* Map of custom properties.\n\t* Custom properties can be added to document fragment instance.\n\t*/\n\t_customProperties = /* @__PURE__ */ new Map();\n\t/**\n\t* Creates new DocumentFragment instance.\n\t*\n\t* @internal\n\t* @param document The document to which this document fragment belongs.\n\t* @param children A list of nodes to be inserted into the created document fragment.\n\t*/\n\tconstructor(document, children) {\n\t\tsuper();\n\t\tthis.document = document;\n\t\tif (children) this._insertChild(0, children);\n\t}\n\t/**\n\t* Iterable interface.\n\t*\n\t* Iterates over nodes added to this document fragment.\n\t*/\n\t[Symbol.iterator]() {\n\t\treturn this._children[Symbol.iterator]();\n\t}\n\t/**\n\t* Number of child nodes in this document fragment.\n\t*/\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\t/**\n\t* Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t*/\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\t/**\n\t* Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t*/\n\tget root() {\n\t\treturn this;\n\t}\n\t/**\n\t* Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t*/\n\tget parent() {\n\t\treturn null;\n\t}\n\t/**\n\t* Artificial element name. Returns `undefined`. Added for compatibility reasons.\n\t*/\n\tget name() {}\n\t/**\n\t* Artificial element getFillerOffset. Returns `undefined`. Added for compatibility reasons.\n\t*/\n\tget getFillerOffset() {}\n\t/**\n\t* Returns the custom property value for the given key.\n\t*/\n\tgetCustomProperty(key) {\n\t\treturn this._customProperties.get(key);\n\t}\n\t/**\n\t* Returns an iterator which iterates over this document fragment's custom properties.\n\t* Iterator provides `[ key, value ]` pairs for each stored property.\n\t*/\n\t*getCustomProperties() {\n\t\tyield* this._customProperties.entries();\n\t}\n\t/**\n\t* Converts `ViewDocumentFragment` instance to plain object and returns it.\n\t* Takes care of converting all of this document fragment's children.\n\t*\n\t* @returns `ViewDocumentFragment` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = [];\n\t\tfor (const node of this._children) json.push(node.toJSON());\n\t\treturn json;\n\t}\n\t/**\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment#_insertChild Insert} a child node or a list of child nodes at the end\n\t* and sets the parent of these nodes to this fragment.\n\t*\n\t* @internal\n\t* @param items Items to be inserted.\n\t* @returns Number of appended nodes.\n\t*/\n\t_appendChild(items) {\n\t\treturn this._insertChild(this.childCount, items);\n\t}\n\t/**\n\t* Gets child at the given index.\n\t*\n\t* @param index Index of child.\n\t* @returns Child node.\n\t*/\n\tgetChild(index) {\n\t\treturn this._children[index];\n\t}\n\t/**\n\t* Gets index of the given child node. Returns `-1` if child node is not found.\n\t*\n\t* @param node Child node.\n\t* @returns Index of the child node.\n\t*/\n\tgetChildIndex(node) {\n\t\treturn this._children.indexOf(node);\n\t}\n\t/**\n\t* Gets child nodes iterator.\n\t*\n\t* @returns Child nodes iterator.\n\t*/\n\tgetChildren() {\n\t\treturn this._children[Symbol.iterator]();\n\t}\n\t/**\n\t* Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t* this fragment.\n\t*\n\t* @internal\n\t* @param index Position where nodes should be inserted.\n\t* @param items Items to be inserted.\n\t* @returns Number of inserted nodes.\n\t*/\n\t_insertChild(index, items) {\n\t\tthis._fireChange(\"children\", this, { index });\n\t\tlet count = 0;\n\t\tconst nodes = normalize$2(this.document, items);\n\t\tfor (const node of nodes) {\n\t\t\tif (node.parent !== null) node._remove();\n\t\t\tnode.parent = this;\n\t\t\tthis._children.splice(index, 0, node);\n\t\t\tindex++;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\t/**\n\t* Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t*\n\t* @internal\n\t* @param index Number of the first node to remove.\n\t* @param howMany Number of nodes to remove.\n\t* @returns The array of removed nodes.\n\t*/\n\t_removeChildren(index, howMany = 1) {\n\t\tthis._fireChange(\"children\", this, { index });\n\t\tfor (let i = index; i < index + howMany; i++) this._children[i].parent = null;\n\t\treturn this._children.splice(index, howMany);\n\t}\n\t/**\n\t* @internal\n\t* @param type Type of the change.\n\t* @param node Changed node.\n\t* @param data Additional data.\n\t* @fires module:engine/view/node~ViewNode#event:change\n\t*/\n\t_fireChange(type, node, data) {\n\t\tthis.fire(`change:${type}`, node, data);\n\t}\n\t/**\n\t* Sets a custom property. They can be used to add special data to elements.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#setCustomProperty\n\t* @internal\n\t*/\n\t_setCustomProperty(key, value) {\n\t\tthis._customProperties.set(key, value);\n\t}\n\t/**\n\t* Removes the custom property stored under the given key.\n\t*\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#removeCustomProperty\n\t* @internal\n\t* @returns Returns true if property was removed.\n\t*/\n\t_removeCustomProperty(key) {\n\t\treturn this._customProperties.delete(key);\n\t}\n};\nViewDocumentFragment.prototype.is = function(type) {\n\treturn type === \"documentFragment\" || type === \"view:documentFragment\";\n};\n/**\n* Converts strings to Text and non-iterables to arrays.\n*/\nfunction normalize$2(document, nodes) {\n\tif (typeof nodes == \"string\") return [new ViewText(document, nodes)];\n\tif (!isIterable(nodes)) nodes = [nodes];\n\treturn Array.from(nodes).map((node) => {\n\t\tif (typeof node == \"string\") return new ViewText(document, node);\n\t\tif (node instanceof ViewTextProxy) return new ViewText(document, node.data);\n\t\treturn node;\n\t});\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/downcastwriter\n*/\n/**\n* View downcast writer.\n*\n* It provides a set of methods used to manipulate view nodes.\n*\n* Do not create an instance of this writer manually. To modify a view structure, use\n* the {@link module:engine/view/view~EditingView#change `View#change()`} block.\n*\n* The `ViewDowncastWriter` is designed to work with semantic views which are the views that were/are being downcasted from the model.\n* To work with ordinary views (e.g. parsed from a pasted content) use the\n* {@link module:engine/view/upcastwriter~ViewUpcastWriter upcast writer}.\n*\n* Read more about changing the view in the {@glink framework/architecture/editing-engine#changing-the-view Changing the view}\n* section of the {@glink framework/architecture/editing-engine Editing engine architecture} guide.\n*/\nvar ViewDowncastWriter = class {\n\t/**\n\t* The view document instance in which this writer operates.\n\t*/\n\tdocument;\n\t/**\n\t* Holds references to the attribute groups that share the same {@link module:engine/view/attributeelement~ViewAttributeElement#id id}.\n\t* The keys are `id`s, the values are `Set`s holding {@link module:engine/view/attributeelement~ViewAttributeElement}s.\n\t*/\n\t_cloneGroups = /* @__PURE__ */ new Map();\n\t/**\n\t* The slot factory used by the `elementToStructure` downcast helper.\n\t*/\n\t_slotFactory = null;\n\t/**\n\t* @param document The view document instance.\n\t*/\n\tconstructor(document) {\n\t\tthis.document = document;\n\t}\n\tsetSelection(...args) {\n\t\tthis.document.selection._setTo(...args);\n\t}\n\t/**\n\t* Moves {@link module:engine/view/documentselection~ViewDocumentSelection#focus selection's focus} to the specified location.\n\t*\n\t* The location can be specified in the same form as\n\t* {@link module:engine/view/view~EditingView#createPositionAt view.createPositionAt()}\n\t* parameters.\n\t*\n\t* @param itemOrPosition\n\t* @param offset Offset or one of the flags. Used only when the first parameter is a {@link module:engine/view/item~ViewItem view item}.\n\t*/\n\tsetSelectionFocus(itemOrPosition, offset) {\n\t\tthis.document.selection._setFocus(itemOrPosition, offset);\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/documentfragment~ViewDocumentFragment} instance.\n\t*\n\t* @param children A list of nodes to be inserted into the created document fragment.\n\t* @returns The created document fragment.\n\t*/\n\tcreateDocumentFragment(children) {\n\t\treturn new ViewDocumentFragment(this.document, children);\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/text~ViewText text node}.\n\t*\n\t* ```ts\n\t* writer.createText( 'foo' );\n\t* ```\n\t*\n\t* @param data The text's data.\n\t* @returns The created text node.\n\t*/\n\tcreateText(data) {\n\t\treturn new ViewText(this.document, data);\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/attributeelement~ViewAttributeElement}.\n\t*\n\t* ```ts\n\t* writer.createAttributeElement( 'strong' );\n\t* writer.createAttributeElement( 'a', { href: 'foo.bar' } );\n\t*\n\t* // Make `<a>` element contain other attributes element so the `<a>` element is not broken.\n\t* writer.createAttributeElement( 'a', { href: 'foo.bar' }, { priority: 5 } );\n\t*\n\t* // Set `id` of a marker element so it is not joined or merged with \"normal\" elements.\n\t* writer.createAttributeElement( 'span', { class: 'my-marker' }, { id: 'marker:my' } );\n\t* ```\n\t*\n\t* @param name Name of the element.\n\t* @param attributes Element's attributes.\n\t* @param options Element's options.\n\t* @param options.priority Element's {@link module:engine/view/attributeelement~ViewAttributeElement#priority priority}.\n\t* @param options.id Element's {@link module:engine/view/attributeelement~ViewAttributeElement#id id}.\n\t* @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t* pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t* @returns Created element.\n\t*/\n\tcreateAttributeElement(name, attributes, options = {}) {\n\t\tconst attributeElement = new ViewAttributeElement(this.document, name, attributes);\n\t\tif (typeof options.priority === \"number\") attributeElement._priority = options.priority;\n\t\tif (options.id) attributeElement._id = options.id;\n\t\tif (options.renderUnsafeAttributes) attributeElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n\t\treturn attributeElement;\n\t}\n\tcreateContainerElement(name, attributes, childrenOrOptions = {}, options = {}) {\n\t\tlet children = void 0;\n\t\tif (isContainerOptions(childrenOrOptions)) options = childrenOrOptions;\n\t\telse children = childrenOrOptions;\n\t\tconst containerElement = new ViewContainerElement(this.document, name, attributes, children);\n\t\tif (options.renderUnsafeAttributes) containerElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n\t\treturn containerElement;\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/editableelement~ViewEditableElement}.\n\t*\n\t* ```ts\n\t* writer.createEditableElement( 'div' );\n\t* writer.createEditableElement( 'div', { id: 'foo-1234' } );\n\t* ```\n\t*\n\t* Note: The editable element is to be used in the editing pipeline. Usually, together with\n\t* {@link module:widget/utils~toWidgetEditable `toWidgetEditable()`}.\n\t*\n\t* @param name Name of the element.\n\t* @param attributes Elements attributes.\n\t* @param options Element's options.\n\t* @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t* pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t* @returns Created element.\n\t*/\n\tcreateEditableElement(name, attributes, options = {}) {\n\t\tconst editableElement = new ViewEditableElement(this.document, name, attributes);\n\t\tif (options.renderUnsafeAttributes) editableElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n\t\treturn editableElement;\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/emptyelement~ViewEmptyElement}.\n\t*\n\t* ```ts\n\t* writer.createEmptyElement( 'img' );\n\t* writer.createEmptyElement( 'img', { id: 'foo-1234' } );\n\t* ```\n\t*\n\t* @param name Name of the element.\n\t* @param attributes Elements attributes.\n\t* @param options Element's options.\n\t* @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t* pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t* @returns Created element.\n\t*/\n\tcreateEmptyElement(name, attributes, options = {}) {\n\t\tconst emptyElement = new ViewEmptyElement(this.document, name, attributes);\n\t\tif (options.renderUnsafeAttributes) emptyElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n\t\treturn emptyElement;\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/uielement~ViewUIElement}.\n\t*\n\t* ```ts\n\t* writer.createUIElement( 'span' );\n\t* writer.createUIElement( 'span', { id: 'foo-1234' } );\n\t* ```\n\t*\n\t* A custom render function can be provided as the third parameter:\n\t*\n\t* ```ts\n\t* writer.createUIElement( 'span', null, function( domDocument ) {\n\t* \tconst domElement = this.toDomElement( domDocument );\n\t* \tdomElement.innerHTML = '<b>this is ui element</b>';\n\t*\n\t* \treturn domElement;\n\t* } );\n\t* ```\n\t*\n\t* Unlike {@link #createRawElement raw elements}, UI elements are by no means editor content, for instance,\n\t* they are ignored by the editor selection system.\n\t*\n\t* You should not use UI elements as data containers. Check out {@link #createRawElement} instead.\n\t*\n\t* @param name The name of the element.\n\t* @param attributes Element attributes.\n\t* @param renderFunction A custom render function.\n\t* @returns The created element.\n\t*/\n\tcreateUIElement(name, attributes, renderFunction) {\n\t\tconst uiElement = new ViewUIElement(this.document, name, attributes);\n\t\tif (renderFunction) uiElement.render = renderFunction;\n\t\treturn uiElement;\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/rawelement~ViewRawElement}.\n\t*\n\t* ```ts\n\t* writer.createRawElement( 'span', { id: 'foo-1234' }, function( domElement ) {\n\t* \tdomElement.innerHTML = '<b>This is the raw content of the raw element.</b>';\n\t* } );\n\t* ```\n\t*\n\t* Raw elements work as data containers (\"wrappers\", \"sandboxes\") but their children are not managed or\n\t* even recognized by the editor. This encapsulation allows integrations to maintain custom DOM structures\n\t* in the editor content without, for instance, worrying about compatibility with other editor features.\n\t* Raw elements are a perfect tool for integration with external frameworks and data sources.\n\t*\n\t* Unlike {@link #createUIElement UI elements}, raw elements act like \"real\" editor content (similar to\n\t* {@link module:engine/view/containerelement~ViewContainerElement} or {@link module:engine/view/emptyelement~ViewEmptyElement}),\n\t* and they are considered by the editor selection.\n\t*\n\t* You should not use raw elements to render the UI in the editor content. Check out {@link #createUIElement `#createUIElement()`}\n\t* instead.\n\t*\n\t* @param name The name of the element.\n\t* @param attributes Element attributes.\n\t* @param renderFunction A custom render function.\n\t* @param options Element's options.\n\t* @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t* pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t* @returns The created element.\n\t*/\n\tcreateRawElement(name, attributes, renderFunction, options = {}) {\n\t\tconst rawElement = new ViewRawElement(this.document, name, attributes);\n\t\tif (renderFunction) rawElement.render = renderFunction;\n\t\tif (options.renderUnsafeAttributes) rawElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n\t\treturn rawElement;\n\t}\n\tsetAttribute(key, value, elementOrOverwrite, element) {\n\t\tif (element !== void 0) element._setAttribute(key, value, elementOrOverwrite);\n\t\telse elementOrOverwrite._setAttribute(key, value);\n\t}\n\tremoveAttribute(key, elementOrTokens, element) {\n\t\tif (element !== void 0) element._removeAttribute(key, elementOrTokens);\n\t\telse elementOrTokens._removeAttribute(key);\n\t}\n\t/**\n\t* Adds specified class to the element.\n\t*\n\t* ```ts\n\t* writer.addClass( 'foo', linkElement );\n\t* writer.addClass( [ 'foo', 'bar' ], linkElement );\n\t* ```\n\t*/\n\taddClass(className, element) {\n\t\telement._addClass(className);\n\t}\n\t/**\n\t* Removes specified class from the element.\n\t*\n\t* ```ts\n\t* writer.removeClass( 'foo', linkElement );\n\t* writer.removeClass( [ 'foo', 'bar' ], linkElement );\n\t* ```\n\t*/\n\tremoveClass(className, element) {\n\t\telement._removeClass(className);\n\t}\n\tsetStyle(property, value, element) {\n\t\tif (isPlainObject(property) && element === void 0) value._setStyle(property);\n\t\telse element._setStyle(property, value);\n\t}\n\t/**\n\t* Removes specified style from the element.\n\t*\n\t* ```ts\n\t* writer.removeStyle( 'color', element ); // Removes 'color' style.\n\t* writer.removeStyle( [ 'color', 'border-top' ], element ); // Removes both 'color' and 'border-top' styles.\n\t* ```\n\t*\n\t* **Note**: This method can work with normalized style names if\n\t* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t* See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t*/\n\tremoveStyle(property, element) {\n\t\telement._removeStyle(property);\n\t}\n\t/**\n\t* Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t* so they can be used to add special data to elements.\n\t*/\n\tsetCustomProperty(key, value, element) {\n\t\telement._setCustomProperty(key, value);\n\t}\n\t/**\n\t* Removes a custom property stored under the given key.\n\t*\n\t* @returns Returns true if property was removed.\n\t*/\n\tremoveCustomProperty(key, element) {\n\t\treturn element._removeCustomProperty(key);\n\t}\n\t/**\n\t* Breaks attribute elements at the provided position or at the boundaries of a provided range. It breaks attribute elements\n\t* up to their first ancestor that is a container element.\n\t*\n\t* In following examples `<p>` is a container, `<b>` and `<u>` are attribute elements:\n\t*\n\t* ```html\n\t* <p>foo<b><u>bar{}</u></b></p> -> <p>foo<b><u>bar</u></b>[]</p>\n\t* <p>foo<b><u>{}bar</u></b></p> -> <p>foo{}<b><u>bar</u></b></p>\n\t* <p>foo<b><u>b{}ar</u></b></p> -> <p>foo<b><u>b</u></b>[]<b><u>ar</u></b></p>\n\t* <p><b>fo{o</b><u>ba}r</u></p> -> <p><b>fo</b><b>o</b><u>ba</u><u>r</u></b></p>\n\t* ```\n\t*\n\t* **Note:** {@link module:engine/view/documentfragment~ViewDocumentFragment DocumentFragment} is treated like a container.\n\t*\n\t* **Note:** The difference between {@link module:engine/view/downcastwriter~ViewDowncastWriter#breakAttributes breakAttributes()} and\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#breakContainer breakContainer()} is that `breakAttributes()` breaks all\n\t* {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements} that are ancestors of a given `position`,\n\t* up to the first encountered {@link module:engine/view/containerelement~ViewContainerElement container element}.\n\t* `breakContainer()` assumes that a given `position` is directly in the container element and breaks that container element.\n\t*\n\t* Throws the `view-writer-invalid-range-container` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t* when the {@link module:engine/view/range~ViewRange#start start}\n\t* and {@link module:engine/view/range~ViewRange#end end} positions of a passed range are not placed inside same parent container.\n\t*\n\t* Throws the `view-writer-cannot-break-empty-element` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t* when trying to break attributes inside an {@link module:engine/view/emptyelement~ViewEmptyElement ViewEmptyElement}.\n\t*\n\t* Throws the `view-writer-cannot-break-ui-element` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t* when trying to break attributes inside a {@link module:engine/view/uielement~ViewUIElement UIElement}.\n\t*\n\t* @see module:engine/view/attributeelement~ViewAttributeElement\n\t* @see module:engine/view/containerelement~ViewContainerElement\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#breakContainer\n\t* @param positionOrRange The position where to break attribute elements.\n\t* @returns The new position or range, after breaking the attribute elements.\n\t*/\n\tbreakAttributes(positionOrRange) {\n\t\tif (positionOrRange instanceof ViewPosition) return this._breakAttributes(positionOrRange);\n\t\telse return this._breakAttributesRange(positionOrRange);\n\t}\n\t/**\n\t* Breaks a {@link module:engine/view/containerelement~ViewContainerElement container view element} into two, at the given position.\n\t* The position has to be directly inside the container element and cannot be in the root. It does not break the conrainer view element\n\t* if the position is at the beginning or at the end of its parent element.\n\t*\n\t* ```html\n\t* <p>foo^bar</p> -> <p>foo</p><p>bar</p>\n\t* <div><p>foo</p>^<p>bar</p></div> -> <div><p>foo</p></div><div><p>bar</p></div>\n\t* <p>^foobar</p> -> ^<p>foobar</p>\n\t* <p>foobar^</p> -> <p>foobar</p>^\n\t* ```\n\t*\n\t* **Note:** The difference between {@link module:engine/view/downcastwriter~ViewDowncastWriter#breakAttributes breakAttributes()} and\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#breakContainer breakContainer()} is that `breakAttributes()` breaks all\n\t* {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements} that are ancestors of a given `position`,\n\t* up to the first encountered {@link module:engine/view/containerelement~ViewContainerElement container element}.\n\t* `breakContainer()` assumes that the given `position` is directly in the container element and breaks that container element.\n\t*\n\t* @see module:engine/view/attributeelement~ViewAttributeElement\n\t* @see module:engine/view/containerelement~ViewContainerElement\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#breakAttributes\n\t* @param position The position where to break the element.\n\t* @returns The position between broken elements. If an element has not been broken,\n\t* the returned position is placed either before or after it.\n\t*/\n\tbreakContainer(position) {\n\t\tconst element = position.parent;\n\t\tif (!element.is(\"containerElement\"))\n /**\n\t\t* Trying to break an element which is not a container element.\n\t\t*\n\t\t* @error view-writer-break-non-container-element\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-break-non-container-element\", this.document);\n\t\tif (!element.parent)\n /**\n\t\t* Trying to break root element.\n\t\t*\n\t\t* @error view-writer-break-root\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-break-root\", this.document);\n\t\tif (position.isAtStart) return ViewPosition._createBefore(element);\n\t\telse if (!position.isAtEnd) {\n\t\t\tconst newElement = element._clone(false);\n\t\t\tthis.insert(ViewPosition._createAfter(element), newElement);\n\t\t\tconst sourceRange = new ViewRange(position, ViewPosition._createAt(element, \"end\"));\n\t\t\tconst targetPosition = new ViewPosition(newElement, 0);\n\t\t\tthis.move(sourceRange, targetPosition);\n\t\t}\n\t\treturn ViewPosition._createAfter(element);\n\t}\n\t/**\n\t* Merges {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements}. It also merges text nodes if needed.\n\t* Only {@link module:engine/view/attributeelement~ViewAttributeElement#isSimilar similar} attribute elements can be merged.\n\t*\n\t* In following examples `<p>` is a container and `<b>` is an attribute element:\n\t*\n\t* ```html\n\t* <p>foo[]bar</p> -> <p>foo{}bar</p>\n\t* <p><b>foo</b>[]<b>bar</b></p> -> <p><b>foo{}bar</b></p>\n\t* <p><b foo=\"bar\">a</b>[]<b foo=\"baz\">b</b></p> -> <p><b foo=\"bar\">a</b>[]<b foo=\"baz\">b</b></p>\n\t* ```\n\t*\n\t* It will also take care about empty attributes when merging:\n\t*\n\t* ```html\n\t* <p><b>[]</b></p> -> <p>[]</p>\n\t* <p><b>foo</b><i>[]</i><b>bar</b></p> -> <p><b>foo{}bar</b></p>\n\t* ```\n\t*\n\t* **Note:** Difference between {@link module:engine/view/downcastwriter~ViewDowncastWriter#mergeAttributes mergeAttributes} and\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#mergeContainers mergeContainers} is that `mergeAttributes` merges two\n\t* {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements} or\n\t* {@link module:engine/view/text~ViewText text nodes} while `mergeContainer` merges two\n\t* {@link module:engine/view/containerelement~ViewContainerElement container elements}.\n\t*\n\t* @see module:engine/view/attributeelement~ViewAttributeElement\n\t* @see module:engine/view/containerelement~ViewContainerElement\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#mergeContainers\n\t* @param position Merge position.\n\t* @returns Position after merge.\n\t*/\n\tmergeAttributes(position) {\n\t\tconst positionOffset = position.offset;\n\t\tconst positionParent = position.parent;\n\t\tif (positionParent.is(\"$text\")) return position;\n\t\tif (positionParent.is(\"attributeElement\") && positionParent.childCount === 0) {\n\t\t\tconst parent = positionParent.parent;\n\t\t\tconst offset = positionParent.index;\n\t\t\tpositionParent._remove();\n\t\t\tthis._removeFromClonedElementsGroup(positionParent);\n\t\t\treturn this.mergeAttributes(new ViewPosition(parent, offset));\n\t\t}\n\t\tconst nodeBefore = positionParent.getChild(positionOffset - 1);\n\t\tconst nodeAfter = positionParent.getChild(positionOffset);\n\t\tif (!nodeBefore || !nodeAfter) return position;\n\t\tif (nodeBefore.is(\"$text\") && nodeAfter.is(\"$text\")) return mergeTextNodes(nodeBefore, nodeAfter);\n\t\telse if (nodeBefore.is(\"attributeElement\") && nodeAfter.is(\"attributeElement\") && nodeBefore.isSimilar(nodeAfter)) {\n\t\t\tconst count = nodeBefore.childCount;\n\t\t\tnodeBefore._appendChild(nodeAfter.getChildren());\n\t\t\tnodeAfter._remove();\n\t\t\tthis._removeFromClonedElementsGroup(nodeAfter);\n\t\t\treturn this.mergeAttributes(new ViewPosition(nodeBefore, count));\n\t\t}\n\t\treturn position;\n\t}\n\t/**\n\t* Merges two {@link module:engine/view/containerelement~ViewContainerElement container elements} that are\n\t* before and after given position. Precisely, the element after the position is removed and it's contents are\n\t* moved to element before the position.\n\t*\n\t* ```html\n\t* <p>foo</p>^<p>bar</p> -> <p>foo^bar</p>\n\t* <div>foo</div>^<p>bar</p> -> <div>foo^bar</div>\n\t* ```\n\t*\n\t* **Note:** Difference between {@link module:engine/view/downcastwriter~ViewDowncastWriter#mergeAttributes mergeAttributes} and\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#mergeContainers mergeContainers} is that `mergeAttributes` merges two\n\t* {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements} or\n\t* {@link module:engine/view/text~ViewText text nodes} while `mergeContainer` merges two\n\t* {@link module:engine/view/containerelement~ViewContainerElement container elements}.\n\t*\n\t* @see module:engine/view/attributeelement~ViewAttributeElement\n\t* @see module:engine/view/containerelement~ViewContainerElement\n\t* @see module:engine/view/downcastwriter~ViewDowncastWriter#mergeAttributes\n\t* @param position Merge position.\n\t* @returns Position after merge.\n\t*/\n\tmergeContainers(position) {\n\t\tconst prev = position.nodeBefore;\n\t\tconst next = position.nodeAfter;\n\t\tif (!prev || !next || !prev.is(\"containerElement\") || !next.is(\"containerElement\"))\n /**\n\t\t* Element before and after given position cannot be merged.\n\t\t*\n\t\t* @error view-writer-merge-containers-invalid-position\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-merge-containers-invalid-position\", this.document);\n\t\tconst lastChild = prev.getChild(prev.childCount - 1);\n\t\tconst newPosition = lastChild instanceof ViewText ? ViewPosition._createAt(lastChild, \"end\") : ViewPosition._createAt(prev, \"end\");\n\t\tthis.move(ViewRange._createIn(next), ViewPosition._createAt(prev, \"end\"));\n\t\tthis.remove(ViewRange._createOn(next));\n\t\treturn newPosition;\n\t}\n\t/**\n\t* Inserts a node or nodes at specified position. Takes care about breaking attributes before insertion\n\t* and merging them afterwards.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n\t* contains instances that are not {@link module:engine/view/text~ViewText Texts},\n\t* {@link module:engine/view/attributeelement~ViewAttributeElement ViewAttributeElements},\n\t* {@link module:engine/view/containerelement~ViewContainerElement ViewContainerElements},\n\t* {@link module:engine/view/emptyelement~ViewEmptyElement ViewEmptyElements},\n\t* {@link module:engine/view/rawelement~ViewRawElement RawElements} or\n\t* {@link module:engine/view/uielement~ViewUIElement UIElements}.\n\t*\n\t* @param position Insertion position.\n\t* @param nodes Node or nodes to insert.\n\t* @returns Range around inserted nodes.\n\t*/\n\tinsert(position, nodes) {\n\t\tnodes = isIterable(nodes) ? [...nodes] : [nodes];\n\t\tvalidateNodesToInsert(nodes, this.document);\n\t\tconst nodeGroups = nodes.reduce((groups, node) => {\n\t\t\tconst lastGroup = groups[groups.length - 1];\n\t\t\tconst breakAttributes = !node.is(\"uiElement\");\n\t\t\tif (!lastGroup || lastGroup.breakAttributes != breakAttributes) groups.push({\n\t\t\t\tbreakAttributes,\n\t\t\t\tnodes: [node]\n\t\t\t});\n\t\t\telse lastGroup.nodes.push(node);\n\t\t\treturn groups;\n\t\t}, []);\n\t\tlet start = null;\n\t\tlet end = position;\n\t\tfor (const { nodes, breakAttributes } of nodeGroups) {\n\t\t\tconst range = this._insertNodes(end, nodes, breakAttributes);\n\t\t\tif (!start) start = range.start;\n\t\t\tend = range.end;\n\t\t}\n\t\tif (!start) return new ViewRange(position);\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Removes provided range from the container.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t* {@link module:engine/view/range~ViewRange#start start} and {@link module:engine/view/range~ViewRange#end end}\n\t* positions are not placed inside same parent container.\n\t*\n\t* @param rangeOrItem Range to remove from container\n\t* or an {@link module:engine/view/item~ViewItem item} to remove. If range is provided, after removing, it will be updated\n\t* to a collapsed range showing the new position.\n\t* @returns Document fragment containing removed nodes.\n\t*/\n\tremove(rangeOrItem) {\n\t\tconst range = rangeOrItem instanceof ViewRange ? rangeOrItem : ViewRange._createOn(rangeOrItem);\n\t\tvalidateRangeContainer(range, this.document);\n\t\tif (range.isCollapsed) return new ViewDocumentFragment(this.document);\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange(range, true);\n\t\tconst parentContainer = breakStart.parent;\n\t\tconst count = breakEnd.offset - breakStart.offset;\n\t\tconst removed = parentContainer._removeChildren(breakStart.offset, count);\n\t\tfor (const node of removed) this._removeFromClonedElementsGroup(node);\n\t\tconst mergePosition = this.mergeAttributes(breakStart);\n\t\trange.start = mergePosition;\n\t\trange.end = mergePosition.clone();\n\t\treturn new ViewDocumentFragment(this.document, removed);\n\t}\n\t/**\n\t* Removes matching elements from given range.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t* {@link module:engine/view/range~ViewRange#start start} and {@link module:engine/view/range~ViewRange#end end}\n\t* positions are not placed inside same parent container.\n\t*\n\t* @param range Range to clear.\n\t* @param element Element to remove.\n\t*/\n\tclear(range, element) {\n\t\tvalidateRangeContainer(range, this.document);\n\t\tconst walker = range.getWalker({\n\t\t\tdirection: \"backward\",\n\t\t\tignoreElementEnd: true\n\t\t});\n\t\tfor (const current of walker) {\n\t\t\tconst item = current.item;\n\t\t\tlet rangeToRemove;\n\t\t\tif (item.is(\"element\") && element.isSimilar(item)) rangeToRemove = ViewRange._createOn(item);\n\t\t\telse if (!current.nextPosition.isAfter(range.start) && item.is(\"$textProxy\")) {\n\t\t\t\tconst parentElement = item.getAncestors().find((ancestor) => {\n\t\t\t\t\treturn ancestor.is(\"element\") && element.isSimilar(ancestor);\n\t\t\t\t});\n\t\t\t\tif (parentElement) rangeToRemove = ViewRange._createIn(parentElement);\n\t\t\t}\n\t\t\tif (rangeToRemove) {\n\t\t\t\tif (rangeToRemove.end.isAfter(range.end)) rangeToRemove.end = range.end;\n\t\t\t\tif (rangeToRemove.start.isBefore(range.start)) rangeToRemove.start = range.start;\n\t\t\t\tthis.remove(rangeToRemove);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* Moves nodes from provided range to target position.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t* {@link module:engine/view/range~ViewRange#start start} and {@link module:engine/view/range~ViewRange#end end}\n\t* positions are not placed inside same parent container.\n\t*\n\t* @param sourceRange Range containing nodes to move.\n\t* @param targetPosition Position to insert.\n\t* @returns Range in target container. Inserted nodes are placed between\n\t* {@link module:engine/view/range~ViewRange#start start} and {@link module:engine/view/range~ViewRange#end end} positions.\n\t*/\n\tmove(sourceRange, targetPosition) {\n\t\tlet nodes;\n\t\tif (targetPosition.isAfter(sourceRange.end)) {\n\t\t\ttargetPosition = this._breakAttributes(targetPosition, true);\n\t\t\tconst parent = targetPosition.parent;\n\t\t\tconst countBefore = parent.childCount;\n\t\t\tsourceRange = this._breakAttributesRange(sourceRange, true);\n\t\t\tnodes = this.remove(sourceRange);\n\t\t\ttargetPosition.offset += parent.childCount - countBefore;\n\t\t} else nodes = this.remove(sourceRange);\n\t\treturn this.insert(targetPosition, nodes);\n\t}\n\t/**\n\t* Wraps elements within range with provided {@link module:engine/view/attributeelement~ViewAttributeElement ViewAttributeElement}.\n\t* If a collapsed range is provided, it will be wrapped only if it is equal to view selection.\n\t*\n\t* If a collapsed range was passed and is same as selection, the selection\n\t* will be moved to the inside of the wrapped attribute element.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-invalid-range-container`\n\t* when {@link module:engine/view/range~ViewRange#start}\n\t* and {@link module:engine/view/range~ViewRange#end} positions are not placed inside same parent container.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t* an instance of {@link module:engine/view/attributeelement~ViewAttributeElement ViewAttributeElement}.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-nonselection-collapsed-range` when passed range\n\t* is collapsed and different than view selection.\n\t*\n\t* @param range Range to wrap.\n\t* @param attribute Attribute element to use as wrapper.\n\t* @returns range Range after wrapping, spanning over wrapping attribute element.\n\t*/\n\twrap(range, attribute) {\n\t\tif (!(attribute instanceof ViewAttributeElement)) throw new CKEditorError(\"view-writer-wrap-invalid-attribute\", this.document);\n\t\tvalidateRangeContainer(range, this.document);\n\t\tif (!range.isCollapsed) return this._wrapRange(range, attribute);\n\t\telse {\n\t\t\tlet position = range.start;\n\t\t\tif (position.parent.is(\"element\") && !_hasNonUiChildren(position.parent)) position = position.getLastMatchingPosition((value) => value.item.is(\"uiElement\"));\n\t\t\tposition = this._wrapPosition(position, attribute);\n\t\t\tconst viewSelection = this.document.selection;\n\t\t\tif (viewSelection.isCollapsed && viewSelection.getFirstPosition().isEqual(range.start)) this.setSelection(position);\n\t\t\treturn new ViewRange(position);\n\t\t}\n\t}\n\t/**\n\t* Unwraps nodes within provided range from attribute element.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t* {@link module:engine/view/range~ViewRange#start start} and {@link module:engine/view/range~ViewRange#end end}\n\t* positions are not placed inside same parent container.\n\t*/\n\tunwrap(range, attribute) {\n\t\tif (!(attribute instanceof ViewAttributeElement))\n /**\n\t\t* The `attribute` passed to {@link module:engine/view/downcastwriter~ViewDowncastWriter#unwrap `ViewDowncastWriter#unwrap()`}\n\t\t* must be an instance of {@link module:engine/view/attributeelement~ViewAttributeElement `AttributeElement`}.\n\t\t*\n\t\t* @error view-writer-unwrap-invalid-attribute\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-unwrap-invalid-attribute\", this.document);\n\t\tvalidateRangeContainer(range, this.document);\n\t\tif (range.isCollapsed) return range;\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange(range, true);\n\t\tconst parentContainer = breakStart.parent;\n\t\tconst newRange = this._unwrapChildren(parentContainer, breakStart.offset, breakEnd.offset, attribute);\n\t\tconst start = this.mergeAttributes(newRange.start);\n\t\tif (!start.isEqual(newRange.start)) newRange.end.offset--;\n\t\tconst end = this.mergeAttributes(newRange.end);\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Renames element by creating a copy of renamed element but with changed name and then moving contents of the\n\t* old element to the new one. Keep in mind that this will invalidate all {@link module:engine/view/position~ViewPosition positions}\n\t* which has renamed element as {@link module:engine/view/position~ViewPosition#parent a parent}.\n\t*\n\t* New element has to be created because `Element#tagName` property in DOM is readonly.\n\t*\n\t* Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t*\n\t* @param newName New name for element.\n\t* @param viewElement Element to be renamed.\n\t* @returns Element created due to rename.\n\t*/\n\trename(newName, viewElement) {\n\t\tconst newElement = new ViewContainerElement(this.document, newName, viewElement.getAttributes());\n\t\tthis.insert(ViewPosition._createAfter(viewElement), newElement);\n\t\tthis.move(ViewRange._createIn(viewElement), ViewPosition._createAt(newElement, 0));\n\t\tthis.remove(ViewRange._createOn(viewElement));\n\t\treturn newElement;\n\t}\n\t/**\n\t* Cleans up memory by removing obsolete cloned elements group from the writer.\n\t*\n\t* Should be used whenever all {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements}\n\t* with the same {@link module:engine/view/attributeelement~ViewAttributeElement#id id} are going to be removed from the view and\n\t* the group will no longer be needed.\n\t*\n\t* Cloned elements group are not removed automatically in case if the group is still needed after all its elements\n\t* were removed from the view.\n\t*\n\t* Keep in mind that group names are equal to the `id` property of the attribute element.\n\t*\n\t* @param groupName Name of the group to clear.\n\t*/\n\tclearClonedElementsGroup(groupName) {\n\t\tthis._cloneGroups.delete(groupName);\n\t}\n\t/**\n\t* Creates position at the given location. The location can be specified as:\n\t*\n\t* * a {@link module:engine/view/position~ViewPosition position},\n\t* * parent element and offset (offset defaults to `0`),\n\t* * parent element and `'end'` (sets position at the end of that element),\n\t* * {@link module:engine/view/item~ViewItem view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t*\n\t* This method is a shortcut to other constructors such as:\n\t*\n\t* * {@link #createPositionBefore},\n\t* * {@link #createPositionAfter},\n\t*\n\t* @param offset Offset or one of the flags. Used only when the first parameter is a {@link module:engine/view/item~ViewItem view item}.\n\t*/\n\tcreatePositionAt(itemOrPosition, offset) {\n\t\treturn ViewPosition._createAt(itemOrPosition, offset);\n\t}\n\t/**\n\t* Creates a new position after given view item.\n\t*\n\t* @param item View item after which the position should be located.\n\t*/\n\tcreatePositionAfter(item) {\n\t\treturn ViewPosition._createAfter(item);\n\t}\n\t/**\n\t* Creates a new position before given view item.\n\t*\n\t* @param item View item before which the position should be located.\n\t*/\n\tcreatePositionBefore(item) {\n\t\treturn ViewPosition._createBefore(item);\n\t}\n\t/**\n\t* Creates a range spanning from `start` position to `end` position.\n\t*\n\t* **Note:** This factory method creates its own {@link module:engine/view/position~ViewPosition} instances basing on passed values.\n\t*\n\t* @param start Start position.\n\t* @param end End position. If not set, range will be collapsed at `start` position.\n\t*/\n\tcreateRange(start, end) {\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Creates a range that starts before given {@link module:engine/view/item~ViewItem view item} and ends after it.\n\t*/\n\tcreateRangeOn(item) {\n\t\treturn ViewRange._createOn(item);\n\t}\n\t/**\n\t* Creates a range inside an {@link module:engine/view/element~ViewElement element} which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* @param element Element which is a parent for the range.\n\t*/\n\tcreateRangeIn(element) {\n\t\treturn ViewRange._createIn(element);\n\t}\n\tcreateSelection(...args) {\n\t\treturn new ViewSelection(...args);\n\t}\n\t/**\n\t* Creates placeholders for child elements of the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n\t* `elementToStructure()`} conversion helper.\n\t*\n\t* ```ts\n\t* const viewSlot = conversionApi.writer.createSlot();\n\t* const viewPosition = conversionApi.writer.createPositionAt( viewElement, 0 );\n\t*\n\t* conversionApi.writer.insert( viewPosition, viewSlot );\n\t* ```\n\t*\n\t* It could be filtered down to a specific subset of children (only `<foo>` model elements in this case):\n\t*\n\t* ```ts\n\t* const viewSlot = conversionApi.writer.createSlot( node => node.is( 'element', 'foo' ) );\n\t* const viewPosition = conversionApi.writer.createPositionAt( viewElement, 0 );\n\t*\n\t* conversionApi.writer.insert( viewPosition, viewSlot );\n\t* ```\n\t*\n\t* While providing a filtered slot, make sure to provide slots for all child nodes. A single node cannot be downcasted into\n\t* multiple slots.\n\t*\n\t* **Note**: You should not change the order of nodes. View elements should be in the same order as model nodes.\n\t*\n\t* @param modeOrFilter The filter for child nodes.\n\t* @returns The slot element to be placed in to the view structure while processing\n\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure `elementToStructure()`}.\n\t*/\n\tcreateSlot(modeOrFilter = \"children\") {\n\t\tif (!this._slotFactory)\n /**\n\t\t* The `createSlot()` method is only allowed inside the `elementToStructure` downcast helper callback.\n\t\t*\n\t\t* @error view-writer-invalid-create-slot-context\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-invalid-create-slot-context\", this.document);\n\t\treturn this._slotFactory(this, modeOrFilter);\n\t}\n\t/**\n\t* Registers a slot factory.\n\t*\n\t* @internal\n\t* @param slotFactory The slot factory.\n\t*/\n\t_registerSlotFactory(slotFactory) {\n\t\tthis._slotFactory = slotFactory;\n\t}\n\t/**\n\t* Clears the registered slot factory.\n\t*\n\t* @internal\n\t*/\n\t_clearSlotFactory() {\n\t\tthis._slotFactory = null;\n\t}\n\t/**\n\t* Inserts a node or nodes at the specified position. Takes care of breaking attributes before insertion\n\t* and merging them afterwards if requested by the breakAttributes param.\n\t*\n\t* @param position Insertion position.\n\t* @param nodes Node or nodes to insert.\n\t* @param breakAttributes Whether attributes should be broken.\n\t* @returns Range around inserted nodes.\n\t*/\n\t_insertNodes(position, nodes, breakAttributes) {\n\t\tlet parentElement;\n\t\tif (breakAttributes) parentElement = getParentContainer(position);\n\t\telse parentElement = position.parent.is(\"$text\") ? position.parent.parent : position.parent;\n\t\tif (!parentElement)\n /**\n\t\t* Position's parent container cannot be found.\n\t\t*\n\t\t* @error view-writer-invalid-position-container\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-invalid-position-container\", this.document);\n\t\tlet insertionPosition;\n\t\tif (breakAttributes) insertionPosition = this._breakAttributes(position, true);\n\t\telse insertionPosition = position.parent.is(\"$text\") ? breakTextNode(position) : position;\n\t\tconst length = parentElement._insertChild(insertionPosition.offset, nodes);\n\t\tfor (const node of nodes) this._addToClonedElementsGroup(node);\n\t\tconst endPosition = insertionPosition.getShiftedBy(length);\n\t\tconst start = this.mergeAttributes(insertionPosition);\n\t\tif (!start.isEqual(insertionPosition)) endPosition.offset--;\n\t\tconst end = this.mergeAttributes(endPosition);\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Wraps children with provided `wrapElement`. Only children contained in `parent` element between\n\t* `startOffset` and `endOffset` will be wrapped.\n\t*/\n\t_wrapChildren(parent, startOffset, endOffset, wrapElement) {\n\t\tlet i = startOffset;\n\t\tconst wrapPositions = [];\n\t\twhile (i < endOffset) {\n\t\t\tconst child = parent.getChild(i);\n\t\t\tconst isText = child.is(\"$text\");\n\t\t\tconst isAttribute = child.is(\"attributeElement\");\n\t\t\tif (isAttribute && child._canMergeAttributesFrom(wrapElement)) {\n\t\t\t\tchild._mergeAttributesFrom(wrapElement);\n\t\t\t\twrapPositions.push(new ViewPosition(parent, i));\n\t\t\t} else if (isText || !isAttribute || shouldABeOutsideB(wrapElement, child)) {\n\t\t\t\tconst newAttribute = wrapElement._clone();\n\t\t\t\tchild._remove();\n\t\t\t\tnewAttribute._appendChild(child);\n\t\t\t\tparent._insertChild(i, newAttribute);\n\t\t\t\tthis._addToClonedElementsGroup(newAttribute);\n\t\t\t\twrapPositions.push(new ViewPosition(parent, i));\n\t\t\t} else this._wrapChildren(child, 0, child.childCount, wrapElement);\n\t\t\ti++;\n\t\t}\n\t\tlet offsetChange = 0;\n\t\tfor (const position of wrapPositions) {\n\t\t\tposition.offset -= offsetChange;\n\t\t\tif (position.offset == startOffset) continue;\n\t\t\tif (!this.mergeAttributes(position).isEqual(position)) {\n\t\t\t\toffsetChange++;\n\t\t\t\tendOffset--;\n\t\t\t}\n\t\t}\n\t\treturn ViewRange._createFromParentsAndOffsets(parent, startOffset, parent, endOffset);\n\t}\n\t/**\n\t* Unwraps children from provided `unwrapElement`. Only children contained in `parent` element between\n\t* `startOffset` and `endOffset` will be unwrapped.\n\t*/\n\t_unwrapChildren(parent, startOffset, endOffset, unwrapElement) {\n\t\tlet i = startOffset;\n\t\tconst unwrapPositions = [];\n\t\twhile (i < endOffset) {\n\t\t\tconst child = parent.getChild(i);\n\t\t\tif (!child.is(\"attributeElement\")) {\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (child.isSimilar(unwrapElement)) {\n\t\t\t\tconst unwrapped = child.getChildren();\n\t\t\t\tconst count = child.childCount;\n\t\t\t\tchild._remove();\n\t\t\t\tparent._insertChild(i, unwrapped);\n\t\t\t\tthis._removeFromClonedElementsGroup(child);\n\t\t\t\tunwrapPositions.push(new ViewPosition(parent, i), new ViewPosition(parent, i + count));\n\t\t\t\ti += count;\n\t\t\t\tendOffset += count - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (child._canSubtractAttributesOf(unwrapElement)) {\n\t\t\t\tchild._subtractAttributesOf(unwrapElement);\n\t\t\t\tunwrapPositions.push(new ViewPosition(parent, i), new ViewPosition(parent, i + 1));\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis._unwrapChildren(child, 0, child.childCount, unwrapElement);\n\t\t\ti++;\n\t\t}\n\t\tlet offsetChange = 0;\n\t\tfor (const position of unwrapPositions) {\n\t\t\tposition.offset -= offsetChange;\n\t\t\tif (position.offset == startOffset || position.offset == endOffset) continue;\n\t\t\tif (!this.mergeAttributes(position).isEqual(position)) {\n\t\t\t\toffsetChange++;\n\t\t\t\tendOffset--;\n\t\t\t}\n\t\t}\n\t\treturn ViewRange._createFromParentsAndOffsets(parent, startOffset, parent, endOffset);\n\t}\n\t/**\n\t* Helper function for `view.writer.wrap`. Wraps range with provided attribute element.\n\t* This method will also merge newly added attribute element with its siblings whenever possible.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t* an instance of {@link module:engine/view/attributeelement~ViewAttributeElement ViewAttributeElement}.\n\t*\n\t* @returns New range after wrapping, spanning over wrapping attribute element.\n\t*/\n\t_wrapRange(range, attribute) {\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange(range, true);\n\t\tconst parentContainer = breakStart.parent;\n\t\tconst newRange = this._wrapChildren(parentContainer, breakStart.offset, breakEnd.offset, attribute);\n\t\tconst start = this.mergeAttributes(newRange.start);\n\t\tif (!start.isEqual(newRange.start)) newRange.end.offset--;\n\t\tconst end = this.mergeAttributes(newRange.end);\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Helper function for {@link #wrap}. Wraps position with provided attribute element.\n\t* This method will also merge newly added attribute element with its siblings whenever possible.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t* an instance of {@link module:engine/view/attributeelement~ViewAttributeElement ViewAttributeElement}.\n\t*\n\t* @returns New position after wrapping.\n\t*/\n\t_wrapPosition(position, attribute) {\n\t\tif (attribute.isSimilar(position.parent)) return movePositionToTextNode(position.clone());\n\t\tif (position.parent.is(\"$text\")) position = breakTextNode(position);\n\t\tconst fakeElement = this.createAttributeElement(\"_wrapPosition-fake-element\");\n\t\tfakeElement._priority = Number.POSITIVE_INFINITY;\n\t\tfakeElement.isSimilar = () => false;\n\t\tposition.parent._insertChild(position.offset, fakeElement);\n\t\tconst wrapRange = new ViewRange(position, position.getShiftedBy(1));\n\t\tthis.wrap(wrapRange, attribute);\n\t\tconst newPosition = new ViewPosition(fakeElement.parent, fakeElement.index);\n\t\tfakeElement._remove();\n\t\tconst nodeBefore = newPosition.nodeBefore;\n\t\tconst nodeAfter = newPosition.nodeAfter;\n\t\tif (nodeBefore && nodeBefore.is(\"view:$text\") && nodeAfter && nodeAfter.is(\"view:$text\")) return mergeTextNodes(nodeBefore, nodeAfter);\n\t\treturn movePositionToTextNode(newPosition);\n\t}\n\t/**\n\t* Helper function used by other `ViewDowncastWriter` methods. Breaks attribute elements at the boundaries of given range.\n\t*\n\t* @param range Range which `start` and `end` positions will be used to break attributes.\n\t* @param forceSplitText If set to `true`, will break text nodes even if they are directly in container element.\n\t* This behavior will result in incorrect view state, but is needed by other view writing methods which then fixes view state.\n\t* @returns New range with located at break positions.\n\t*/\n\t_breakAttributesRange(range, forceSplitText = false) {\n\t\tconst rangeStart = range.start;\n\t\tconst rangeEnd = range.end;\n\t\tvalidateRangeContainer(range, this.document);\n\t\tif (range.isCollapsed) {\n\t\t\tconst position = this._breakAttributes(range.start, forceSplitText);\n\t\t\treturn new ViewRange(position, position);\n\t\t}\n\t\tconst breakEnd = this._breakAttributes(rangeEnd, forceSplitText);\n\t\tconst count = breakEnd.parent.childCount;\n\t\tconst breakStart = this._breakAttributes(rangeStart, forceSplitText);\n\t\tbreakEnd.offset += breakEnd.parent.childCount - count;\n\t\treturn new ViewRange(breakStart, breakEnd);\n\t}\n\t/**\n\t* Helper function used by other `ViewDowncastWriter` methods. Breaks attribute elements at given position.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-empty-element` when break position\n\t* is placed inside {@link module:engine/view/emptyelement~ViewEmptyElement ViewEmptyElement}.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-ui-element` when break position\n\t* is placed inside {@link module:engine/view/uielement~ViewUIElement UIElement}.\n\t*\n\t* @param position Position where to break attributes.\n\t* @param forceSplitText If set to `true`, will break text nodes even if they are directly in container element.\n\t* This behavior will result in incorrect view state, but is needed by other view writing methods which then fixes view state.\n\t* @returns New position after breaking the attributes.\n\t*/\n\t_breakAttributes(position, forceSplitText = false) {\n\t\tconst positionOffset = position.offset;\n\t\tconst positionParent = position.parent;\n\t\tif (position.parent.is(\"emptyElement\"))\n /**\n\t\t* Cannot break an `EmptyElement` instance.\n\t\t*\n\t\t* This error is thrown if\n\t\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#breakAttributes `ViewDowncastWriter#breakAttributes()`}\n\t\t* was executed in an incorrect position.\n\t\t*\n\t\t* @error view-writer-cannot-break-empty-element\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-cannot-break-empty-element\", this.document);\n\t\tif (position.parent.is(\"uiElement\"))\n /**\n\t\t* Cannot break a `UIElement` instance.\n\t\t*\n\t\t* This error is thrown if\n\t\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#breakAttributes `ViewDowncastWriter#breakAttributes()`}\n\t\t* was executed in an incorrect position.\n\t\t*\n\t\t* @error view-writer-cannot-break-ui-element\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-cannot-break-ui-element\", this.document);\n\t\tif (position.parent.is(\"rawElement\"))\n /**\n\t\t* Cannot break a `RawElement` instance.\n\t\t*\n\t\t* This error is thrown if\n\t\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#breakAttributes `ViewDowncastWriter#breakAttributes()`}\n\t\t* was executed in an incorrect position.\n\t\t*\n\t\t* @error view-writer-cannot-break-raw-element\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-cannot-break-raw-element\", this.document);\n\t\tif (!forceSplitText && positionParent.is(\"$text\") && isContainerOrFragment(positionParent.parent)) return position.clone();\n\t\tif (isContainerOrFragment(positionParent)) return position.clone();\n\t\tif (positionParent.is(\"$text\")) return this._breakAttributes(breakTextNode(position), forceSplitText);\n\t\tif (positionOffset == positionParent.childCount) {\n\t\t\tconst newPosition = new ViewPosition(positionParent.parent, positionParent.index + 1);\n\t\t\treturn this._breakAttributes(newPosition, forceSplitText);\n\t\t} else if (positionOffset === 0) {\n\t\t\tconst newPosition = new ViewPosition(positionParent.parent, positionParent.index);\n\t\t\treturn this._breakAttributes(newPosition, forceSplitText);\n\t\t} else {\n\t\t\tconst offsetAfter = positionParent.index + 1;\n\t\t\tconst clonedNode = positionParent._clone();\n\t\t\tpositionParent.parent._insertChild(offsetAfter, clonedNode);\n\t\t\tthis._addToClonedElementsGroup(clonedNode);\n\t\t\tconst count = positionParent.childCount - positionOffset;\n\t\t\tconst nodesToMove = positionParent._removeChildren(positionOffset, count);\n\t\t\tclonedNode._appendChild(nodesToMove);\n\t\t\tconst newPosition = new ViewPosition(positionParent.parent, offsetAfter);\n\t\t\treturn this._breakAttributes(newPosition, forceSplitText);\n\t\t}\n\t}\n\t/**\n\t* Stores the information that an {@link module:engine/view/attributeelement~ViewAttributeElement attribute element} was\n\t* added to the tree. Saves the reference to the group in the given element and updates the group, so other elements\n\t* from the group now keep a reference to the given attribute element.\n\t*\n\t* The clones group can be obtained using {@link module:engine/view/attributeelement~ViewAttributeElement#getElementsWithSameId}.\n\t*\n\t* Does nothing if added element has no {@link module:engine/view/attributeelement~ViewAttributeElement#id id}.\n\t*\n\t* @param element Attribute element to save.\n\t*/\n\t_addToClonedElementsGroup(element) {\n\t\tif (!element.root.is(\"rootElement\")) return;\n\t\tif (element.is(\"element\")) for (const child of element.getChildren()) this._addToClonedElementsGroup(child);\n\t\tconst id = element.id;\n\t\tif (!id) return;\n\t\tlet group = this._cloneGroups.get(id);\n\t\tif (!group) {\n\t\t\tgroup = /* @__PURE__ */ new Set();\n\t\t\tthis._cloneGroups.set(id, group);\n\t\t}\n\t\tgroup.add(element);\n\t\telement._clonesGroup = group;\n\t}\n\t/**\n\t* Removes all the information about the given {@link module:engine/view/attributeelement~ViewAttributeElement attribute element}\n\t* from its clones group.\n\t*\n\t* Keep in mind, that the element will still keep a reference to the group (but the group will not keep a reference to it).\n\t* This allows to reference the whole group even if the element was already removed from the tree.\n\t*\n\t* Does nothing if the element has no {@link module:engine/view/attributeelement~ViewAttributeElement#id id}.\n\t*\n\t* @param element Attribute element to remove.\n\t*/\n\t_removeFromClonedElementsGroup(element) {\n\t\tif (element.is(\"element\")) for (const child of element.getChildren()) this._removeFromClonedElementsGroup(child);\n\t\tconst id = element.id;\n\t\tif (!id) return;\n\t\tconst group = this._cloneGroups.get(id);\n\t\tif (!group) return;\n\t\tgroup.delete(element);\n\t}\n};\nfunction _hasNonUiChildren(parent) {\n\treturn Array.from(parent.getChildren()).some((child) => !child.is(\"uiElement\"));\n}\n/**\n* The `attribute` passed to {@link module:engine/view/downcastwriter~ViewDowncastWriter#wrap `ViewDowncastWriter#wrap()`}\n* must be an instance of {@link module:engine/view/attributeelement~ViewAttributeElement `AttributeElement`}.\n*\n* @error view-writer-wrap-invalid-attribute\n*/\n/**\n* Returns first parent container of specified {@link module:engine/view/position~ViewPosition Position}.\n* Position's parent node is checked as first, then next parents are checked.\n* Note that {@link module:engine/view/documentfragment~ViewDocumentFragment DocumentFragment} is treated like a container.\n*\n* @param position Position used as a start point to locate parent container.\n* @returns Parent container element or `undefined` if container is not found.\n*/\nfunction getParentContainer(position) {\n\tlet parent = position.parent;\n\twhile (!isContainerOrFragment(parent)) {\n\t\tif (!parent) return;\n\t\tparent = parent.parent;\n\t}\n\treturn parent;\n}\n/**\n* Checks if first {@link module:engine/view/attributeelement~ViewAttributeElement ViewAttributeElement} provided to the function\n* can be wrapped outside second element. It is done by comparing elements'\n* {@link module:engine/view/attributeelement~ViewAttributeElement#priority priorities}, if both have same priority\n* {@link module:engine/view/element~ViewElement#getIdentity identities} are compared.\n*/\nfunction shouldABeOutsideB(a, b) {\n\tif (a.priority < b.priority) return true;\n\telse if (a.priority > b.priority) return false;\n\treturn a.getIdentity() < b.getIdentity();\n}\n/**\n* Returns new position that is moved to near text node. Returns same position if there is no text node before of after\n* specified position.\n*\n* ```html\n* <p>foo[]</p> -> <p>foo{}</p>\n* <p>[]foo</p> -> <p>{}foo</p>\n* ```\n*\n* @returns Position located inside text node or same position if there is no text nodes\n* before or after position location.\n*/\nfunction movePositionToTextNode(position) {\n\tconst nodeBefore = position.nodeBefore;\n\tif (nodeBefore && nodeBefore.is(\"$text\")) return new ViewPosition(nodeBefore, nodeBefore.data.length);\n\tconst nodeAfter = position.nodeAfter;\n\tif (nodeAfter && nodeAfter.is(\"$text\")) return new ViewPosition(nodeAfter, 0);\n\treturn position;\n}\n/**\n* Breaks text node into two text nodes when possible.\n*\n* ```html\n* <p>foo{}bar</p> -> <p>foo[]bar</p>\n* <p>{}foobar</p> -> <p>[]foobar</p>\n* <p>foobar{}</p> -> <p>foobar[]</p>\n* ```\n*\n* @param position Position that need to be placed inside text node.\n* @returns New position after breaking text node.\n*/\nfunction breakTextNode(position) {\n\tif (position.offset == position.parent.data.length) return new ViewPosition(position.parent.parent, position.parent.index + 1);\n\tif (position.offset === 0) return new ViewPosition(position.parent.parent, position.parent.index);\n\tconst textToMove = position.parent.data.slice(position.offset);\n\tposition.parent._data = position.parent.data.slice(0, position.offset);\n\tposition.parent.parent._insertChild(position.parent.index + 1, new ViewText(position.root.document, textToMove));\n\treturn new ViewPosition(position.parent.parent, position.parent.index + 1);\n}\n/**\n* Merges two text nodes into first node. Removes second node and returns merge position.\n*\n* @param t1 First text node to merge. Data from second text node will be moved at the end of this text node.\n* @param t2 Second text node to merge. This node will be removed after merging.\n* @returns Position after merging text nodes.\n*/\nfunction mergeTextNodes(t1, t2) {\n\tconst nodeBeforeLength = t1.data.length;\n\tt1._data += t2.data;\n\tt2._remove();\n\treturn new ViewPosition(t1, nodeBeforeLength);\n}\nconst validNodesToInsert = [\n\tViewText,\n\tViewAttributeElement,\n\tViewContainerElement,\n\tViewEmptyElement,\n\tViewRawElement,\n\tViewUIElement\n];\n/**\n* Checks if provided nodes are valid to insert.\n*\n* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n* contains instances that are not supported ones (see error description for valid ones.\n*/\nfunction validateNodesToInsert(nodes, errorContext) {\n\tfor (const node of nodes) {\n\t\tif (!validNodesToInsert.some((validNode) => node instanceof validNode))\n /**\n\t\t* One of the nodes to be inserted is of an invalid type.\n\t\t*\n\t\t* Nodes to be inserted with {@link module:engine/view/downcastwriter~ViewDowncastWriter#insert `ViewDowncastWriter#insert()`}\n\t\t* should be of the following types:\n\t\t*\n\t\t* * {@link module:engine/view/attributeelement~ViewAttributeElement ViewAttributeElement},\n\t\t* * {@link module:engine/view/containerelement~ViewContainerElement ViewContainerElement},\n\t\t* * {@link module:engine/view/emptyelement~ViewEmptyElement ViewEmptyElement},\n\t\t* * {@link module:engine/view/uielement~ViewUIElement UIElement},\n\t\t* * {@link module:engine/view/rawelement~ViewRawElement RawElement},\n\t\t* * {@link module:engine/view/text~ViewText Text}.\n\t\t*\n\t\t* @error view-writer-insert-invalid-node-type\n\t\t*/\n\t\tthrow new CKEditorError(\"view-writer-insert-invalid-node-type\", errorContext);\n\t\tif (!node.is(\"$text\")) validateNodesToInsert(node.getChildren(), errorContext);\n\t}\n}\n/**\n* Checks if node is ViewContainerElement or DocumentFragment, because in most cases they should be treated the same way.\n*\n* @returns Returns `true` if node is instance of ViewContainerElement or DocumentFragment.\n*/\nfunction isContainerOrFragment(node) {\n\treturn node && (node.is(\"containerElement\") || node.is(\"documentFragment\"));\n}\n/**\n* Checks if {@link module:engine/view/range~ViewRange#start range start} and {@link module:engine/view/range~ViewRange#end range end}\n* are placed inside same {@link module:engine/view/containerelement~ViewContainerElement container element}.\n* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when validation fails.\n*/\nfunction validateRangeContainer(range, errorContext) {\n\tconst startContainer = getParentContainer(range.start);\n\tconst endContainer = getParentContainer(range.end);\n\tif (!startContainer || !endContainer || startContainer !== endContainer)\n /**\n\t* The container of the given range is invalid.\n\t*\n\t* This may happen if {@link module:engine/view/range~ViewRange#start range start} and\n\t* {@link module:engine/view/range~ViewRange#end range end} positions are not placed inside the same container element or\n\t* a parent container for these positions cannot be found.\n\t*\n\t* Methods like {@link module:engine/view/downcastwriter~ViewDowncastWriter#wrap `ViewDowncastWriter#remove()`},\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#wrap `ViewDowncastWriter#clean()`},\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#wrap `ViewDowncastWriter#wrap()`},\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#wrap `ViewDowncastWriter#unwrap()`} need to be called\n\t* on a range that has its start and end positions located in the same container element. Both positions can be\n\t* nested within other elements (e.g. an attribute element) but the closest container ancestor must be the same.\n\t*\n\t* @error view-writer-invalid-range-container\n\t*/\n\tthrow new CKEditorError(\"view-writer-invalid-range-container\", errorContext);\n}\n/**\n* Checks if the provided argument is a plain object that can be used as options for container element.\n*/\nfunction isContainerOptions(childrenOrOptions) {\n\treturn isPlainObject(childrenOrOptions);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Set of utilities related to handling block and inline fillers.\n*\n* Browsers do not allow to put caret in elements which does not have height. Because of it, we need to fill all\n* empty elements which should be selectable with elements or characters called \"fillers\". Unfortunately there is no one\n* universal filler, this is why two types are uses:\n*\n* * Block filler is an element which fill block elements, like `<p>`. CKEditor uses `<br>` as a block filler during the editing,\n* as browsers do natively. So instead of an empty `<p>` there will be `<p><br></p>`. The advantage of block filler is that\n* it is transparent for the selection, so when the caret is before the `<br>` and user presses right arrow he will be\n* moved to the next paragraph, not after the `<br>`. The disadvantage is that it breaks a block, so it cannot be used\n* in the middle of a line of text. The {@link module:engine/view/filler~BR_FILLER `<br>` filler} can be replaced with any other\n* character in the data output, for instance {@link module:engine/view/filler~NBSP_FILLER non-breaking space} or\n* {@link module:engine/view/filler~MARKED_NBSP_FILLER marked non-breaking space}.\n*\n* * Inline filler is a filler which does not break a line of text, so it can be used inside the text, for instance in the empty\n* `<b>` surrendered by text: `foo<b></b>bar`, if we want to put the caret there. CKEditor uses a sequence of the zero-width\n* spaces as an {@link module:engine/view/filler~INLINE_FILLER inline filler} having the predetermined\n* {@link module:engine/view/filler~INLINE_FILLER_LENGTH length}. A sequence is used, instead of a single character to\n* avoid treating random zero-width spaces as the inline filler. Disadvantage of the inline filler is that it is not\n* transparent for the selection. The arrow key moves the caret between zero-width spaces characters, so the additional\n* code is needed to handle the caret.\n*\n* Both inline and block fillers are handled by the {@link module:engine/view/renderer~ViewRenderer renderer} and are not present in the\n* view.\n*\n* @module engine/view/filler\n*/\n/**\n* Non-breaking space filler creator. This function creates the `&nbsp;` text node.\n* It defines how the filler is created.\n*\n* @see module:engine/view/filler~MARKED_NBSP_FILLER\n* @see module:engine/view/filler~BR_FILLER\n* @internal\n*/\nconst NBSP_FILLER = (domDocument) => domDocument.createTextNode(\"\\xA0\");\n/**\n* Marked non-breaking space filler creator. This function creates the `<span data-cke-filler=\"true\">&nbsp;</span>` element.\n* It defines how the filler is created.\n*\n* @see module:engine/view/filler~NBSP_FILLER\n* @see module:engine/view/filler~BR_FILLER\n* @internal\n*/\nconst MARKED_NBSP_FILLER = (domDocument) => {\n\tconst span = domDocument.createElement(\"span\");\n\tspan.dataset.ckeFiller = \"true\";\n\tspan.innerText = \"\\xA0\";\n\treturn span;\n};\n/**\n* `<br>` filler creator. This function creates the `<br data-cke-filler=\"true\">` element.\n* It defines how the filler is created.\n*\n* @see module:engine/view/filler~NBSP_FILLER\n* @see module:engine/view/filler~MARKED_NBSP_FILLER\n* @internal\n*/\nconst BR_FILLER = (domDocument) => {\n\tconst fillerBr = domDocument.createElement(\"br\");\n\tfillerBr.dataset.ckeFiller = \"true\";\n\treturn fillerBr;\n};\n/**\n* Length of the {@link module:engine/view/filler~INLINE_FILLER INLINE_FILLER}.\n*\n* @internal\n*/\nconst INLINE_FILLER_LENGTH = 7;\n/**\n* Inline filler which is a sequence of the word joiners.\n*\n* @internal\n*/\nconst INLINE_FILLER = \"⁠\".repeat(7);\n/**\n* Checks if the node is a text node which starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n*\n* ```ts\n* startsWithFiller( document.createTextNode( INLINE_FILLER ) ); // true\n* startsWithFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // true\n* startsWithFiller( document.createTextNode( 'foo' ) ); // false\n* startsWithFiller( document.createElement( 'p' ) ); // false\n* ```\n*\n* @param domNode DOM node.\n* @returns True if the text node starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n* @internal\n*/\nfunction startsWithFiller(domNode) {\n\tif (typeof domNode == \"string\") return domNode.substr(0, 7) === INLINE_FILLER;\n\treturn isText(domNode) && domNode.data.substr(0, 7) === INLINE_FILLER;\n}\n/**\n* Checks if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n*\n* ```ts\n* isInlineFiller( document.createTextNode( INLINE_FILLER ) ); // true\n* isInlineFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // false\n* ```\n*\n* @param domText DOM text node.\n* @returns True if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n* @internal\n*/\nfunction isInlineFiller(domText) {\n\treturn domText.data.length == 7 && startsWithFiller(domText);\n}\n/**\n* Get string data from the text node, removing an {@link module:engine/view/filler~INLINE_FILLER inline filler} from it,\n* if text node contains it.\n*\n* ```ts\n* getDataWithoutFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ) == 'foo' // true\n* getDataWithoutFiller( document.createTextNode( 'foo' ) ) == 'foo' // true\n* ```\n*\n* @param domText DOM text node, possible with inline filler.\n* @returns Data without filler.\n* @internal\n*/\nfunction getDataWithoutFiller(domText) {\n\tconst data = typeof domText == \"string\" ? domText : domText.data;\n\tif (startsWithFiller(domText)) return data.slice(7);\n\treturn data;\n}\n/**\n* Assign key observer which move cursor from the end of the inline filler to the beginning of it when\n* the left arrow is pressed, so the filler does not break navigation.\n*\n* @param view View controller instance we should inject quirks handling on.\n* @internal\n*/\nfunction injectQuirksHandling(view) {\n\tview.document.on(\"arrowKey\", jumpOverInlineFiller, { priority: \"low\" });\n}\n/**\n* Move cursor from the end of the inline filler to the beginning of it when, so the filler does not break navigation.\n*/\nfunction jumpOverInlineFiller(evt, data) {\n\tif (data.keyCode == keyCodes.arrowleft) {\n\t\tconst domSelection = data.domTarget.ownerDocument.defaultView.getSelection();\n\t\tif (domSelection.rangeCount == 1 && domSelection.getRangeAt(0).collapsed) {\n\t\t\tconst domParent = domSelection.getRangeAt(0).startContainer;\n\t\t\tconst domOffset = domSelection.getRangeAt(0).startOffset;\n\t\t\tif (startsWithFiller(domParent) && domOffset <= 7) domSelection.collapse(domParent, 0);\n\t\t}\n\t}\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/renderer\n*/\nconst ViewRendererBase = /* #__PURE__ */ ObservableMixin();\n/**\n* Renderer is responsible for updating the DOM structure and the DOM selection based on\n* the {@link module:engine/view/renderer~ViewRenderer#markToSync information about updated view nodes}.\n* In other words, it renders the view to the DOM.\n*\n* Its main responsibility is to make only the necessary, minimal changes to the DOM. However, unlike in many\n* virtual DOM implementations, the primary reason for doing minimal changes is not the performance but ensuring\n* that native editing features such as text composition, autocompletion, spell checking, selection's x-index are\n* affected as little as possible.\n*\n* Renderer uses {@link module:engine/view/domconverter~ViewDomConverter} to transform view nodes and positions\n* to and from the DOM.\n*/\nvar ViewRenderer = class extends ViewRendererBase {\n\t/**\n\t* Set of DOM Documents instances.\n\t*/\n\tdomDocuments = /* @__PURE__ */ new Set();\n\t/**\n\t* Converter instance.\n\t*/\n\tdomConverter;\n\t/**\n\t* Set of nodes which attributes changed and may need to be rendered.\n\t*/\n\tmarkedAttributes = /* @__PURE__ */ new Set();\n\t/**\n\t* Set of elements which child lists changed and may need to be rendered.\n\t*/\n\tmarkedChildren = /* @__PURE__ */ new Set();\n\t/**\n\t* Set of text nodes which text data changed and may need to be rendered.\n\t*/\n\tmarkedTexts = /* @__PURE__ */ new Set();\n\t/**\n\t* View selection. Renderer updates DOM selection based on the view selection.\n\t*/\n\tselection;\n\t/**\n\t* The text node in which the inline filler was rendered.\n\t*/\n\t_inlineFiller = null;\n\t/**\n\t* DOM element containing fake selection.\n\t*/\n\t_fakeSelectionContainer = null;\n\t/**\n\t* Creates a renderer instance.\n\t*\n\t* @param domConverter Converter instance.\n\t* @param selection View selection.\n\t*/\n\tconstructor(domConverter, selection) {\n\t\tsuper();\n\t\tthis.domConverter = domConverter;\n\t\tthis.selection = selection;\n\t\tthis.set(\"isFocused\", false);\n\t\tthis.set(\"isSelecting\", false);\n\t\tthis.set(\"isComposing\", false);\n\t\tif (env.isBlink && !env.isAndroid) this.on(\"change:isSelecting\", () => {\n\t\t\tif (!this.isSelecting) this.render();\n\t\t});\n\t}\n\t/**\n\t* Marks a view node to be updated in the DOM by {@link #render `render()`}.\n\t*\n\t* Note that only view nodes whose parents have corresponding DOM elements need to be marked to be synchronized.\n\t*\n\t* @see #markedAttributes\n\t* @see #markedChildren\n\t* @see #markedTexts\n\t*\n\t* @param type Type of the change.\n\t* @param node ViewNode to be marked.\n\t*/\n\tmarkToSync(type, node) {\n\t\tif (type === \"text\") {\n\t\t\tif (this.domConverter.mapViewToDom(node.parent)) this.markedTexts.add(node);\n\t\t} else {\n\t\t\tif (!this.domConverter.mapViewToDom(node)) return;\n\t\t\tif (type === \"attributes\") this.markedAttributes.add(node);\n\t\t\telse if (type === \"children\") this.markedChildren.add(node);\n\t\t\telse\n /**\n\t\t\t* Unknown type passed to Renderer.markToSync.\n\t\t\t*\n\t\t\t* @error view-renderer-unknown-type\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"view-renderer-unknown-type\", this);\n\t\t}\n\t}\n\t/**\n\t* Renders all buffered changes ({@link #markedAttributes}, {@link #markedChildren} and {@link #markedTexts}) and\n\t* the current view selection (if needed) to the DOM by applying a minimal set of changes to it.\n\t*\n\t* Renderer tries not to break the text composition (e.g. IME) and x-index of the selection,\n\t* so it does as little as it is needed to update the DOM.\n\t*\n\t* Renderer also handles {@link module:engine/view/filler fillers}. Especially, it checks if the inline filler is needed\n\t* at the selection position and adds or removes it. To prevent breaking text composition inline filler will not be\n\t* removed as long as the selection is in the text node which needed it at first.\n\t*/\n\trender() {\n\t\tif (this.isComposing && !env.isAndroid) return;\n\t\tlet inlineFillerPosition = null;\n\t\tconst isInlineFillerRenderingPossible = env.isBlink && !env.isAndroid ? !this.isSelecting : true;\n\t\tfor (const element of this.markedChildren) this._updateChildrenMappings(element);\n\t\tif (isInlineFillerRenderingPossible) {\n\t\t\tif (this._inlineFiller && !this._isSelectionInInlineFiller()) this._removeInlineFiller();\n\t\t\tif (this._inlineFiller) inlineFillerPosition = this._getInlineFillerPosition();\n\t\t\telse if (this._needsInlineFillerAtSelection()) {\n\t\t\t\tinlineFillerPosition = this.selection.getFirstPosition();\n\t\t\t\tthis.markedChildren.add(inlineFillerPosition.parent);\n\t\t\t}\n\t\t} else if (this._inlineFiller && this._inlineFiller.parentNode) {\n\t\t\tinlineFillerPosition = this.domConverter.domPositionToView(this._inlineFiller);\n\t\t\tif (inlineFillerPosition && inlineFillerPosition.parent.is(\"$text\")) inlineFillerPosition = ViewPosition._createBefore(inlineFillerPosition.parent);\n\t\t}\n\t\tfor (const element of this.markedAttributes) this._updateAttrs(element);\n\t\tfor (const element of this.markedChildren) this._updateChildren(element, { inlineFillerPosition });\n\t\tfor (const node of this.markedTexts) if (!this.markedChildren.has(node.parent) && this.domConverter.mapViewToDom(node.parent)) this._updateText(node, { inlineFillerPosition });\n\t\tif (isInlineFillerRenderingPossible) if (inlineFillerPosition) {\n\t\t\tconst fillerDomPosition = this.domConverter.viewPositionToDom(inlineFillerPosition);\n\t\t\tconst domDocument = fillerDomPosition.parent.ownerDocument;\n\t\t\tif (!startsWithFiller(fillerDomPosition.parent)) this._inlineFiller = addInlineFiller(domDocument, fillerDomPosition.parent, fillerDomPosition.offset);\n\t\t\telse this._inlineFiller = fillerDomPosition.parent;\n\t\t} else this._inlineFiller = null;\n\t\tthis._updateFocus();\n\t\tthis._updateSelection();\n\t\tthis.domConverter._clearTemporaryCustomProperties();\n\t\tthis.markedTexts.clear();\n\t\tthis.markedAttributes.clear();\n\t\tthis.markedChildren.clear();\n\t}\n\t/**\n\t* Updates mappings of view element's children.\n\t*\n\t* Children that were replaced in the view structure by similar elements (same tag name) are treated as 'replaced'.\n\t* This means that their mappings can be updated so the new view elements are mapped to the existing DOM elements.\n\t* Thanks to that these elements do not need to be re-rendered completely.\n\t*\n\t* @param viewElement The view element whose children mappings will be updated.\n\t*/\n\t_updateChildrenMappings(viewElement) {\n\t\tconst domElement = this.domConverter.mapViewToDom(viewElement);\n\t\tif (!domElement) return;\n\t\tconst actualDomChildren = Array.from(domElement.childNodes);\n\t\tconst expectedDomChildren = Array.from(this.domConverter.viewChildrenToDom(viewElement, { withChildren: false }));\n\t\tconst diff = this._diffNodeLists(actualDomChildren, expectedDomChildren);\n\t\tconst actions = this._findUpdateActions(diff, actualDomChildren, expectedDomChildren, areSimilarElements);\n\t\tif (actions.indexOf(\"update\") !== -1) {\n\t\t\tconst counter = {\n\t\t\t\tequal: 0,\n\t\t\t\tinsert: 0,\n\t\t\t\tdelete: 0\n\t\t\t};\n\t\t\tfor (const action of actions) if (action === \"update\") {\n\t\t\t\tconst insertIndex = counter.equal + counter.insert;\n\t\t\t\tconst deleteIndex = counter.equal + counter.delete;\n\t\t\t\tconst viewChild = viewElement.getChild(insertIndex);\n\t\t\t\tif (viewChild && !viewChild.is(\"uiElement\") && !viewChild.is(\"rawElement\")) this._updateElementMappings(viewChild, actualDomChildren[deleteIndex]);\n\t\t\t\tremove$1(expectedDomChildren[insertIndex]);\n\t\t\t\tcounter.equal++;\n\t\t\t} else counter[action]++;\n\t\t}\n\t}\n\t/**\n\t* Updates mappings of a given view element.\n\t*\n\t* @param viewElement The view element whose mappings will be updated.\n\t* @param domElement The DOM element representing the given view element.\n\t*/\n\t_updateElementMappings(viewElement, domElement) {\n\t\tthis.domConverter.unbindDomElement(domElement);\n\t\tthis.domConverter.bindElements(domElement, viewElement);\n\t\tthis.markedChildren.add(viewElement);\n\t\tthis.markedAttributes.add(viewElement);\n\t}\n\t/**\n\t* Gets the position of the inline filler based on the current selection.\n\t* Here, we assume that we know that the filler is needed and\n\t* {@link #_isSelectionInInlineFiller is at the selection position}, and, since it is needed,\n\t* it is somewhere at the selection position.\n\t*\n\t* Note: The filler position cannot be restored based on the filler's DOM text node, because\n\t* when this method is called (before rendering), the bindings will often be broken. View-to-DOM\n\t* bindings are only dependable after rendering.\n\t*/\n\t_getInlineFillerPosition() {\n\t\tconst firstPos = this.selection.getFirstPosition();\n\t\tif (firstPos.parent.is(\"$text\")) return ViewPosition._createBefore(firstPos.parent);\n\t\telse return firstPos;\n\t}\n\t/**\n\t* Returns `true` if the selection has not left the inline filler's text node.\n\t* If it is `true`, it means that the filler had been added for a reason and the selection did not\n\t* leave the filler's text node. For example, the user can be in the middle of a composition so it should not be touched.\n\t*\n\t* @returns `true` if the inline filler and selection are in the same place.\n\t*/\n\t_isSelectionInInlineFiller() {\n\t\tif (this.selection.rangeCount != 1 || !this.selection.isCollapsed) return false;\n\t\tconst selectionPosition = this.selection.getFirstPosition();\n\t\tconst position = this.domConverter.viewPositionToDom(selectionPosition);\n\t\tif (position && isText(position.parent) && startsWithFiller(position.parent)) return true;\n\t\treturn false;\n\t}\n\t/**\n\t* Removes the inline filler.\n\t*/\n\t_removeInlineFiller() {\n\t\tconst domFillerNode = this._inlineFiller;\n\t\tif (!startsWithFiller(domFillerNode))\n /**\n\t\t* The inline filler node was lost. Most likely, something overwrote the filler text node\n\t\t* in the DOM.\n\t\t*\n\t\t* @error view-renderer-filler-was-lost\n\t\t*/\n\t\tthrow new CKEditorError(\"view-renderer-filler-was-lost\", this);\n\t\tif (isInlineFiller(domFillerNode)) domFillerNode.remove();\n\t\telse domFillerNode.data = domFillerNode.data.substr(7);\n\t\tthis._inlineFiller = null;\n\t}\n\t/**\n\t* Checks if the inline {@link module:engine/view/filler filler} should be added.\n\t*\n\t* @returns `true` if the inline filler should be added.\n\t*/\n\t_needsInlineFillerAtSelection() {\n\t\tif (this.selection.rangeCount != 1 || !this.selection.isCollapsed) return false;\n\t\tconst selectionPosition = this.selection.getFirstPosition();\n\t\tconst selectionParent = selectionPosition.parent;\n\t\tconst selectionOffset = selectionPosition.offset;\n\t\tif (!this.domConverter.mapViewToDom(selectionParent.root)) return false;\n\t\tif (!selectionParent.is(\"element\")) return false;\n\t\tif (!isEditable(selectionParent)) return false;\n\t\tconst nodeBefore = selectionPosition.nodeBefore;\n\t\tconst nodeAfter = selectionPosition.nodeAfter;\n\t\tif (nodeBefore instanceof ViewText || nodeAfter instanceof ViewText) return false;\n\t\tif (selectionOffset === selectionParent.getFillerOffset() && (!nodeBefore || !nodeBefore.is(\"element\", \"br\"))) return false;\n\t\tif (env.isAndroid && (nodeBefore || nodeAfter)) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Checks if text needs to be updated and possibly updates it.\n\t*\n\t* @param viewText View text to update.\n\t* @param options.inlineFillerPosition The position where the inline filler should be rendered.\n\t*/\n\t_updateText(viewText, options) {\n\t\tconst domText = this.domConverter.findCorrespondingDomText(viewText);\n\t\tlet expectedText = this.domConverter.viewToDom(viewText).data;\n\t\tconst filler = options.inlineFillerPosition;\n\t\tif (filler && filler.parent == viewText.parent && filler.offset == viewText.index) expectedText = INLINE_FILLER + expectedText;\n\t\tthis._updateTextNode(domText, expectedText);\n\t}\n\t/**\n\t* Checks if attribute list needs to be updated and possibly updates it.\n\t*\n\t* @param viewElement The view element to update.\n\t*/\n\t_updateAttrs(viewElement) {\n\t\tconst domElement = this.domConverter.mapViewToDom(viewElement);\n\t\tif (!domElement) return;\n\t\tfor (const domAttr of Array.from(domElement.attributes)) {\n\t\t\tconst key = domAttr.name;\n\t\t\tif (!viewElement.hasAttribute(key)) this.domConverter.removeDomElementAttribute(domElement, key);\n\t\t}\n\t\tfor (const key of viewElement.getAttributeKeys()) this.domConverter.setDomElementAttribute(domElement, key, viewElement.getAttribute(key), viewElement);\n\t}\n\t/**\n\t* Checks if elements child list needs to be updated and possibly updates it.\n\t*\n\t* Note that on Android, to reduce the risk of composition breaks, it tries to update data of an existing\n\t* child text nodes instead of replacing them completely.\n\t*\n\t* @param viewElement View element to update.\n\t* @param options.inlineFillerPosition The position where the inline filler should be rendered.\n\t*/\n\t_updateChildren(viewElement, options) {\n\t\tconst domElement = this.domConverter.mapViewToDom(viewElement);\n\t\tif (!domElement) return;\n\t\tif (env.isAndroid) {\n\t\t\tlet previousDomNode = null;\n\t\t\tfor (const domNode of Array.from(domElement.childNodes)) {\n\t\t\t\tif (previousDomNode && isText(previousDomNode) && isText(domNode)) {\n\t\t\t\t\tdomElement.normalize();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tpreviousDomNode = domNode;\n\t\t\t}\n\t\t}\n\t\tconst inlineFillerPosition = options.inlineFillerPosition;\n\t\tconst actualDomChildren = domElement.childNodes;\n\t\tconst expectedDomChildren = Array.from(this.domConverter.viewChildrenToDom(viewElement, { bind: true }));\n\t\tif (inlineFillerPosition && inlineFillerPosition.parent === viewElement) addInlineFiller(domElement.ownerDocument, expectedDomChildren, inlineFillerPosition.offset);\n\t\tconst diff = this._diffNodeLists(actualDomChildren, expectedDomChildren);\n\t\tconst actions = this._findUpdateActions(diff, actualDomChildren, expectedDomChildren, areTextNodes);\n\t\tlet i = 0;\n\t\tconst nodesToUnbind = /* @__PURE__ */ new Set();\n\t\tfor (const action of actions) if (action === \"delete\") {\n\t\t\tnodesToUnbind.add(actualDomChildren[i]);\n\t\t\tremove$1(actualDomChildren[i]);\n\t\t} else if (action === \"equal\" || action === \"update\") i++;\n\t\ti = 0;\n\t\tfor (const action of actions) if (action === \"insert\") {\n\t\t\tinsertAt(domElement, i, expectedDomChildren[i]);\n\t\t\ti++;\n\t\t} else if (action === \"update\") {\n\t\t\tthis._updateTextNode(actualDomChildren[i], expectedDomChildren[i].data);\n\t\t\ti++;\n\t\t} else if (action === \"equal\") {\n\t\t\tthis._markDescendantTextToSync(this.domConverter.domToView(expectedDomChildren[i]));\n\t\t\ti++;\n\t\t}\n\t\tfor (const node of nodesToUnbind) if (!node.parentNode) this.domConverter.unbindDomElement(node);\n\t}\n\t/**\n\t* Shorthand for diffing two arrays or node lists of DOM nodes.\n\t*\n\t* @param actualDomChildren Actual DOM children\n\t* @param expectedDomChildren Expected DOM children.\n\t* @returns The list of actions based on the {@link module:utils/diff~diff} function.\n\t*/\n\t_diffNodeLists(actualDomChildren, expectedDomChildren) {\n\t\tactualDomChildren = filterOutFakeSelectionContainer(actualDomChildren, this._fakeSelectionContainer);\n\t\treturn diff(actualDomChildren, expectedDomChildren, sameNodes$1.bind(null, this.domConverter));\n\t}\n\t/**\n\t* Finds DOM nodes that were replaced with the similar nodes (same tag name) in the view. All nodes are compared\n\t* within one `insert`/`delete` action group, for example:\n\t*\n\t* ```\n\t* Actual DOM:\t\t<p><b>Foo</b>Bar<i>Baz</i><b>Bax</b></p>\n\t* Expected DOM:\t<p>Bar<b>123</b><i>Baz</i><b>456</b></p>\n\t* Input actions:\t[ insert, insert, delete, delete, equal, insert, delete ]\n\t* Output actions:\t[ insert, replace, delete, equal, replace ]\n\t* ```\n\t*\n\t* @param actions Actions array which is a result of the {@link module:utils/diff~diff} function.\n\t* @param actualDom Actual DOM children\n\t* @param expectedDom Expected DOM children.\n\t* @param comparator A comparator function that should return `true` if the given node should be reused\n\t* (either by the update of a text node data or an element children list for similar elements).\n\t* @returns Actions array modified with the `update` actions.\n\t*/\n\t_findUpdateActions(actions, actualDom, expectedDom, comparator) {\n\t\tif (actions.indexOf(\"insert\") === -1 || actions.indexOf(\"delete\") === -1) return actions;\n\t\tlet newActions = [];\n\t\tlet actualSlice = [];\n\t\tlet expectedSlice = [];\n\t\tconst counter = {\n\t\t\tequal: 0,\n\t\t\tinsert: 0,\n\t\t\tdelete: 0\n\t\t};\n\t\tfor (const action of actions) {\n\t\t\tif (action === \"insert\") expectedSlice.push(expectedDom[counter.equal + counter.insert]);\n\t\t\telse if (action === \"delete\") actualSlice.push(actualDom[counter.equal + counter.delete]);\n\t\t\telse {\n\t\t\t\tnewActions = newActions.concat(diff(actualSlice, expectedSlice, comparator).map((action) => action === \"equal\" ? \"update\" : action));\n\t\t\t\tnewActions.push(\"equal\");\n\t\t\t\tactualSlice = [];\n\t\t\t\texpectedSlice = [];\n\t\t\t}\n\t\t\tcounter[action]++;\n\t\t}\n\t\treturn newActions.concat(diff(actualSlice, expectedSlice, comparator).map((action) => action === \"equal\" ? \"update\" : action));\n\t}\n\t/**\n\t* Checks if text needs to be updated and possibly updates it by removing and inserting only parts\n\t* of the data from the existing text node to reduce impact on the IME composition.\n\t*\n\t* @param domText DOM text node to update.\n\t* @param expectedText The expected data of a text node.\n\t*/\n\t_updateTextNode(domText, expectedText) {\n\t\tconst actualText = domText.data;\n\t\tif (actualText == expectedText) return;\n\t\tif (env.isAndroid && this.isComposing && actualText.replace(/\\u00A0/g, \" \") == expectedText.replace(/\\u00A0/g, \" \")) return;\n\t\tthis._updateTextNodeInternal(domText, expectedText);\n\t}\n\t/**\n\t* Part of the `_updateTextNode` method extracted for easier testing.\n\t*/\n\t_updateTextNodeInternal(domText, expectedText) {\n\t\tconst actions = fastDiff(domText.data, expectedText);\n\t\tfor (const action of actions) if (action.type === \"insert\") domText.insertData(action.index, action.values.join(\"\"));\n\t\telse domText.deleteData(action.index, action.howMany);\n\t}\n\t/**\n\t* Marks text nodes to be synchronized.\n\t*\n\t* If a text node is passed, it will be marked. If an element is passed, all descendant text nodes inside it will be marked.\n\t*\n\t* @param viewNode View node to sync.\n\t*/\n\t_markDescendantTextToSync(viewNode) {\n\t\tif (!viewNode) return;\n\t\tif (viewNode.is(\"$text\")) this.markedTexts.add(viewNode);\n\t\telse if (viewNode.is(\"element\")) for (const child of viewNode.getChildren()) this._markDescendantTextToSync(child);\n\t}\n\t/**\n\t* Checks if the selection needs to be updated and possibly updates it.\n\t*/\n\t_updateSelection() {\n\t\tif (env.isBlink && !env.isAndroid && this.isSelecting && !this.markedChildren.size) return;\n\t\tif (this.selection.rangeCount === 0) {\n\t\t\tthis._removeDomSelection();\n\t\t\tthis._removeFakeSelection();\n\t\t\treturn;\n\t\t}\n\t\tconst domEditable = this.domConverter.mapViewToDom(this.selection.editableElement);\n\t\tif (!this.isFocused || !domEditable) {\n\t\t\tif (!this.selection.isFake && this._fakeSelectionContainer && this._fakeSelectionContainer.isConnected) this._removeFakeSelection();\n\t\t\treturn;\n\t\t}\n\t\tif (this.selection.isFake) this._updateFakeSelection(domEditable);\n\t\telse if (this._fakeSelectionContainer && this._fakeSelectionContainer.isConnected) {\n\t\t\tthis._removeFakeSelection();\n\t\t\tthis._updateDomSelection(domEditable);\n\t\t} else if (!(this.isComposing && env.isAndroid)) this._updateDomSelection(domEditable);\n\t}\n\t/**\n\t* Updates the fake selection.\n\t*\n\t* @param domEditable A valid DOM editable where the fake selection container should be added.\n\t*/\n\t_updateFakeSelection(domEditable) {\n\t\tconst domDocument = domEditable.ownerDocument;\n\t\tif (!this._fakeSelectionContainer) this._fakeSelectionContainer = createFakeSelectionContainer(domDocument);\n\t\tconst container = this._fakeSelectionContainer;\n\t\tthis.domConverter.bindFakeSelection(container, this.selection);\n\t\tif (!this._fakeSelectionNeedsUpdate(domEditable)) return;\n\t\tif (!container.parentElement || container.parentElement != domEditable) domEditable.appendChild(container);\n\t\tcontainer.textContent = this.selection.fakeSelectionLabel || \"\\xA0\";\n\t\tconst domSelection = domDocument.getSelection();\n\t\tconst domRange = domDocument.createRange();\n\t\tdomSelection.removeAllRanges();\n\t\tdomRange.selectNodeContents(container);\n\t\tdomSelection.addRange(domRange);\n\t}\n\t/**\n\t* Updates the DOM selection.\n\t*\n\t* @param domEditable A valid DOM editable where the DOM selection should be rendered.\n\t*/\n\t_updateDomSelection(domEditable) {\n\t\tconst domSelection = domEditable.ownerDocument.defaultView.getSelection();\n\t\tif (!this._domSelectionNeedsUpdate(domSelection)) return;\n\t\tconst anchor = this.domConverter.viewPositionToDom(this.selection.anchor);\n\t\tconst focus = this.domConverter.viewPositionToDom(this.selection.focus);\n\t\tdomSelection.setBaseAndExtent(anchor.parent, anchor.offset, focus.parent, focus.offset);\n\t\tif (env.isGecko) fixGeckoSelectionAfterBr(focus, domSelection);\n\t}\n\t/**\n\t* Checks whether a given DOM selection needs to be updated.\n\t*\n\t* @param domSelection The DOM selection to check.\n\t*/\n\t_domSelectionNeedsUpdate(domSelection) {\n\t\tif (!this.domConverter.isDomSelectionCorrect(domSelection)) return true;\n\t\tconst oldViewSelection = domSelection && this.domConverter.domSelectionToView(domSelection);\n\t\tif (oldViewSelection && this.selection.isEqual(oldViewSelection)) return false;\n\t\tif (!this.selection.isCollapsed && this.selection.isSimilar(oldViewSelection)) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Checks whether the fake selection needs to be updated.\n\t*\n\t* @param domEditable A valid DOM editable where a new fake selection container should be added.\n\t*/\n\t_fakeSelectionNeedsUpdate(domEditable) {\n\t\tconst container = this._fakeSelectionContainer;\n\t\tconst domSelection = domEditable.ownerDocument.getSelection();\n\t\tif (!container || container.parentElement !== domEditable) return true;\n\t\tif (domSelection.anchorNode !== container && !container.contains(domSelection.anchorNode)) return true;\n\t\treturn container.textContent !== this.selection.fakeSelectionLabel;\n\t}\n\t/**\n\t* Removes the DOM selection.\n\t*/\n\t_removeDomSelection() {\n\t\tfor (const doc of this.domDocuments) {\n\t\t\tconst domSelection = doc.getSelection();\n\t\t\tif (domSelection.rangeCount) {\n\t\t\t\tconst activeDomElement = doc.activeElement;\n\t\t\t\tconst viewElement = this.domConverter.mapDomToView(activeDomElement);\n\t\t\t\tif (activeDomElement && viewElement) domSelection.removeAllRanges();\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* Removes the fake selection.\n\t*/\n\t_removeFakeSelection() {\n\t\tconst container = this._fakeSelectionContainer;\n\t\tif (container) container.remove();\n\t}\n\t/**\n\t* Checks if focus needs to be updated and possibly updates it.\n\t*/\n\t_updateFocus() {\n\t\tif (this.isFocused) {\n\t\t\tconst editable = this.selection.editableElement;\n\t\t\tif (editable) this.domConverter.focus(editable);\n\t\t}\n\t}\n};\n/**\n* Checks if provided element is editable.\n*/\nfunction isEditable(element) {\n\tif (element.getAttribute(\"contenteditable\") == \"false\") return false;\n\tconst parent = element.findAncestor((element) => element.hasAttribute(\"contenteditable\"));\n\treturn !parent || parent.getAttribute(\"contenteditable\") == \"true\";\n}\n/**\n* Adds inline filler at a given position.\n*\n* The position can be given as an array of DOM nodes and an offset in that array,\n* or a DOM parent element and an offset in that element.\n*\n* @returns The DOM text node that contains an inline filler.\n*/\nfunction addInlineFiller(domDocument, domParentOrArray, offset) {\n\tconst childNodes = domParentOrArray instanceof Array ? domParentOrArray : domParentOrArray.childNodes;\n\tconst nodeAfterFiller = childNodes[offset];\n\tif (isText(nodeAfterFiller)) {\n\t\tnodeAfterFiller.data = INLINE_FILLER + nodeAfterFiller.data;\n\t\treturn nodeAfterFiller;\n\t} else {\n\t\tconst fillerNode = domDocument.createTextNode(INLINE_FILLER);\n\t\tif (Array.isArray(domParentOrArray)) childNodes.splice(offset, 0, fillerNode);\n\t\telse insertAt(domParentOrArray, offset, fillerNode);\n\t\treturn fillerNode;\n\t}\n}\n/**\n* Whether two DOM nodes should be considered as similar.\n* Nodes are considered similar if they have the same tag name.\n*/\nfunction areSimilarElements(node1, node2) {\n\treturn isNode(node1) && isNode(node2) && !isText(node1) && !isText(node2) && !isComment(node1) && !isComment(node2) && node1.tagName.toLowerCase() === node2.tagName.toLowerCase();\n}\n/**\n* Whether two DOM nodes are text nodes.\n*/\nfunction areTextNodes(node1, node2) {\n\treturn isNode(node1) && isNode(node2) && isText(node1) && isText(node2);\n}\n/**\n* Whether two dom nodes should be considered as the same.\n* Two nodes which are considered the same are:\n*\n* * Text nodes with the same text.\n* * Element nodes represented by the same object.\n* * Two block filler elements.\n*\n* @param blockFillerMode Block filler mode, see {@link module:engine/view/domconverter~ViewDomConverter#blockFillerMode}.\n*/\nfunction sameNodes$1(domConverter, actualDomChild, expectedDomChild) {\n\tif (actualDomChild === expectedDomChild) return true;\n\telse if (isText(actualDomChild) && isText(expectedDomChild)) return actualDomChild.data === expectedDomChild.data;\n\telse if (domConverter.isBlockFiller(actualDomChild) && domConverter.isBlockFiller(expectedDomChild)) return true;\n\treturn false;\n}\n/**\n* The following is a Firefox–specific hack (https://github.com/ckeditor/ckeditor5-engine/issues/1439).\n* When the native DOM selection is at the end of the block and preceded by <br /> e.g.\n*\n* ```html\n* <p>foo<br/>[]</p>\n* ```\n*\n* which happens a lot when using the soft line break, the browser fails to (visually) move the\n* caret to the new line. A quick fix is as simple as force–refreshing the selection with the same range.\n*/\nfunction fixGeckoSelectionAfterBr(focus, domSelection) {\n\tlet parent = focus.parent;\n\tlet offset = focus.offset;\n\tif (isText(parent) && isInlineFiller(parent)) {\n\t\toffset = indexOf(parent) + 1;\n\t\tparent = parent.parentNode;\n\t}\n\tif (parent.nodeType != Node.ELEMENT_NODE || offset != parent.childNodes.length - 1) return;\n\tconst childAtOffset = parent.childNodes[offset];\n\tif (childAtOffset && childAtOffset.tagName == \"BR\") domSelection.addRange(domSelection.getRangeAt(0));\n}\nfunction filterOutFakeSelectionContainer(domChildList, fakeSelectionContainer) {\n\tconst childList = Array.from(domChildList);\n\tif (childList.length == 0 || !fakeSelectionContainer) return childList;\n\tif (childList[childList.length - 1] == fakeSelectionContainer) childList.pop();\n\treturn childList;\n}\n/**\n* Creates a fake selection container for a given document.\n*/\nfunction createFakeSelectionContainer(domDocument) {\n\tconst container = domDocument.createElement(\"div\");\n\tcontainer.className = \"ck-fake-selection-container\";\n\tObject.assign(container.style, {\n\t\tposition: \"fixed\",\n\t\ttop: 0,\n\t\tleft: \"-9999px\",\n\t\twidth: \"42px\"\n\t});\n\tcontainer.textContent = \"\\xA0\";\n\treturn container;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/domconverter\n*/\nconst BR_FILLER_REF = BR_FILLER(global.document);\nconst NBSP_FILLER_REF = NBSP_FILLER(global.document);\nconst MARKED_NBSP_FILLER_REF = MARKED_NBSP_FILLER(global.document);\nconst UNSAFE_ATTRIBUTE_NAME_PREFIX = \"data-ck-unsafe-attribute-\";\nconst UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE = \"data-ck-unsafe-element\";\n/**\n* `ViewDomConverter` is a set of tools to do transformations between DOM nodes and view nodes. It also handles\n* {@link module:engine/view/domconverter~ViewDomConverter#bindElements bindings} between these nodes.\n*\n* An instance of the DOM converter is available under\n* {@link module:engine/view/view~EditingView#domConverter `editor.editing.view.domConverter`}.\n*\n* The DOM converter does not check which nodes should be rendered (use {@link module:engine/view/renderer~ViewRenderer}), does not keep the\n* state of a tree nor keeps the synchronization between the tree view and\n* the DOM tree (use {@link module:engine/view/document~ViewDocument}).\n*\n* The DOM converter keeps DOM elements to view element bindings, so when the converter gets destroyed, the bindings are lost.\n* Two converters will keep separate binding maps, so one tree view can be bound with two DOM trees.\n*/\nvar ViewDomConverter = class {\n\tdocument;\n\t/**\n\t* Whether to leave the View-to-DOM conversion result unchanged or improve editing experience by filtering out interactive data.\n\t*/\n\trenderingMode;\n\t/**\n\t* The mode of a block filler used by the DOM converter.\n\t*/\n\tblockFillerMode;\n\t/**\n\t* Elements which are considered pre-formatted elements.\n\t*/\n\tpreElements;\n\t/**\n\t* Elements which are considered block elements (and hence should be filled with a\n\t* {@link #isBlockFiller block filler}).\n\t*\n\t* Whether an element is considered a block element also affects handling of trailing whitespaces.\n\t*\n\t* You can extend this array if you introduce support for block elements which are not yet recognized here.\n\t*/\n\tblockElements;\n\t/**\n\t* A list of elements that exist inline (in text) but their inner structure cannot be edited because\n\t* of the way they are rendered by the browser. They are mostly HTML form elements but there are other\n\t* elements such as `<img>` or `<iframe>` that also have non-editable children or no children whatsoever.\n\t*\n\t* Whether an element is considered an inline object has an impact on white space rendering (trimming)\n\t* around (and inside of it). In short, white spaces in text nodes next to inline objects are not trimmed.\n\t*\n\t* You can extend this array if you introduce support for inline object elements which are not yet recognized here.\n\t*/\n\tinlineObjectElements;\n\t/**\n\t* A list of elements which may affect the editing experience. To avoid this, those elements are replaced with\n\t* `<span data-ck-unsafe-element=\"[element name]\"></span>` while rendering in the editing mode.\n\t*/\n\tunsafeElements;\n\t/**\n\t* The DOM Document used by `ViewDomConverter` to create DOM nodes.\n\t*/\n\t_domDocument;\n\t/**\n\t* The DOM-to-view mapping.\n\t*/\n\t_domToViewMapping = /* @__PURE__ */ new WeakMap();\n\t/**\n\t* The view-to-DOM mapping.\n\t*/\n\t_viewToDomMapping = /* @__PURE__ */ new WeakMap();\n\t/**\n\t* Holds the mapping between fake selection containers and corresponding view selections.\n\t*/\n\t_fakeSelectionMapping = /* @__PURE__ */ new WeakMap();\n\t/**\n\t* Matcher for view elements whose content should be treated as raw data\n\t* and not processed during the conversion from DOM nodes to view elements.\n\t*/\n\t_rawContentElementMatcher = new Matcher();\n\t/**\n\t* Matcher for inline object view elements. This is an extension of a simple {@link #inlineObjectElements} array of element names.\n\t*/\n\t_inlineObjectElementMatcher = new Matcher();\n\t/**\n\t* Set of elements with temporary custom properties that require clearing after render.\n\t*/\n\t_elementsWithTemporaryCustomProperties = /* @__PURE__ */ new Set();\n\t/**\n\t* Creates a DOM converter.\n\t*\n\t* @param document The view document instance.\n\t* @param options An object with configuration options.\n\t* @param options.blockFillerMode The type of the block filler to use.\n\t* Default value depends on the options.renderingMode:\n\t* 'nbsp' when options.renderingMode == 'data',\n\t* 'br' when options.renderingMode == 'editing'.\n\t* @param options.renderingMode Whether to leave the View-to-DOM conversion result unchanged\n\t* or improve editing experience by filtering out interactive data.\n\t*/\n\tconstructor(document, { blockFillerMode, renderingMode = \"editing\" } = {}) {\n\t\tthis.document = document;\n\t\tthis.renderingMode = renderingMode;\n\t\tthis.blockFillerMode = blockFillerMode || (renderingMode === \"editing\" ? \"br\" : \"nbsp\");\n\t\tthis.preElements = [\"pre\", \"textarea\"];\n\t\tthis.blockElements = [\n\t\t\t\"address\",\n\t\t\t\"article\",\n\t\t\t\"aside\",\n\t\t\t\"blockquote\",\n\t\t\t\"caption\",\n\t\t\t\"center\",\n\t\t\t\"dd\",\n\t\t\t\"details\",\n\t\t\t\"dir\",\n\t\t\t\"div\",\n\t\t\t\"dl\",\n\t\t\t\"dt\",\n\t\t\t\"fieldset\",\n\t\t\t\"figcaption\",\n\t\t\t\"figure\",\n\t\t\t\"footer\",\n\t\t\t\"form\",\n\t\t\t\"h1\",\n\t\t\t\"h2\",\n\t\t\t\"h3\",\n\t\t\t\"h4\",\n\t\t\t\"h5\",\n\t\t\t\"h6\",\n\t\t\t\"header\",\n\t\t\t\"hgroup\",\n\t\t\t\"legend\",\n\t\t\t\"li\",\n\t\t\t\"main\",\n\t\t\t\"menu\",\n\t\t\t\"nav\",\n\t\t\t\"ol\",\n\t\t\t\"p\",\n\t\t\t\"pre\",\n\t\t\t\"section\",\n\t\t\t\"summary\",\n\t\t\t\"table\",\n\t\t\t\"tbody\",\n\t\t\t\"td\",\n\t\t\t\"tfoot\",\n\t\t\t\"th\",\n\t\t\t\"thead\",\n\t\t\t\"tr\",\n\t\t\t\"ul\"\n\t\t];\n\t\tthis.inlineObjectElements = [\n\t\t\t\"object\",\n\t\t\t\"iframe\",\n\t\t\t\"input\",\n\t\t\t\"button\",\n\t\t\t\"textarea\",\n\t\t\t\"select\",\n\t\t\t\"option\",\n\t\t\t\"video\",\n\t\t\t\"embed\",\n\t\t\t\"audio\",\n\t\t\t\"img\",\n\t\t\t\"canvas\"\n\t\t];\n\t\tthis.unsafeElements = [\"script\", \"style\"];\n\t\tthis._domDocument = this.renderingMode === \"editing\" ? global.document : global.document.implementation.createHTMLDocument(\"\");\n\t}\n\t/**\n\t* The DOM Document used by `ViewDomConverter` to create DOM nodes.\n\t*/\n\tget domDocument() {\n\t\treturn this._domDocument;\n\t}\n\t/**\n\t* Binds a given DOM element that represents fake selection to a **position** of a\n\t* {@link module:engine/view/documentselection~ViewDocumentSelection document selection}.\n\t* Document selection copy is stored and can be retrieved by the\n\t* {@link module:engine/view/domconverter~ViewDomConverter#fakeSelectionToView} method.\n\t*/\n\tbindFakeSelection(domElement, viewDocumentSelection) {\n\t\tthis._fakeSelectionMapping.set(domElement, new ViewSelection(viewDocumentSelection));\n\t}\n\t/**\n\t* Returns a {@link module:engine/view/selection~ViewSelection view selection} instance corresponding to a given\n\t* DOM element that represents fake selection. Returns `undefined` if binding to the given DOM element does not exist.\n\t*/\n\tfakeSelectionToView(domElement) {\n\t\treturn this._fakeSelectionMapping.get(domElement);\n\t}\n\t/**\n\t* Binds DOM and view elements, so it will be possible to get corresponding elements using\n\t* {@link module:engine/view/domconverter~ViewDomConverter#mapDomToView} and\n\t* {@link module:engine/view/domconverter~ViewDomConverter#mapViewToDom}.\n\t*\n\t* @param domElement The DOM element to bind.\n\t* @param viewElement The view element to bind.\n\t*/\n\tbindElements(domElement, viewElement) {\n\t\tthis._domToViewMapping.set(domElement, viewElement);\n\t\tthis._viewToDomMapping.set(viewElement, domElement);\n\t}\n\t/**\n\t* Unbinds a given DOM element from the view element it was bound to. Unbinding is deep, meaning that all children of\n\t* the DOM element will be unbound too.\n\t*\n\t* @param domElement The DOM element to unbind.\n\t*/\n\tunbindDomElement(domElement) {\n\t\tconst viewElement = this._domToViewMapping.get(domElement);\n\t\tif (viewElement) {\n\t\t\tthis._domToViewMapping.delete(domElement);\n\t\t\tthis._viewToDomMapping.delete(viewElement);\n\t\t\tfor (const child of domElement.children) this.unbindDomElement(child);\n\t\t}\n\t}\n\t/**\n\t* Binds DOM and view document fragments, so it will be possible to get corresponding document fragments using\n\t* {@link module:engine/view/domconverter~ViewDomConverter#mapDomToView} and\n\t* {@link module:engine/view/domconverter~ViewDomConverter#mapViewToDom}.\n\t*\n\t* @param domFragment The DOM document fragment to bind.\n\t* @param viewFragment The view document fragment to bind.\n\t*/\n\tbindDocumentFragments(domFragment, viewFragment) {\n\t\tthis._domToViewMapping.set(domFragment, viewFragment);\n\t\tthis._viewToDomMapping.set(viewFragment, domFragment);\n\t}\n\t/**\n\t* Decides whether a given pair of attribute key and value should be passed further down the pipeline.\n\t*\n\t* @param elementName Element name in lower case.\n\t*/\n\tshouldRenderAttribute(attributeKey, attributeValue, elementName) {\n\t\tif (this.renderingMode === \"data\") return true;\n\t\tattributeKey = attributeKey.toLowerCase();\n\t\tif (attributeKey.startsWith(\"on\")) return false;\n\t\tif (attributeKey === \"srcdoc\") return false;\n\t\tif (elementName === \"img\" && (attributeKey === \"src\" || attributeKey === \"srcset\")) return true;\n\t\tif (elementName === \"source\" && attributeKey === \"srcset\") return true;\n\t\tattributeValue = attributeValue.replace(/[\\s\\u0000-\\u0020]+/g, \"\");\n\t\tif (attributeValue.match(/^javascript:/i)) return false;\n\t\tif (attributeValue.match(/^data:/i)) {\n\t\t\tconst isImage = attributeValue.match(/^data:image\\/(png|jpeg|jpg|gif|webp|avif|bmp|x-icon|vnd\\.microsoft\\.icon|apng|tiff|heic|heif|jxl)($|[;,])/i);\n\t\t\tconst isMedia = attributeValue.match(/^data:(audio|video)\\/(mp4|mpeg|mp3|ogg|webm|wav|x-wav|aac|flac|quicktime|3gpp)($|[;,])/i);\n\t\t\tif (!isImage && !isMedia) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Set `domElement`'s content using provided `html` argument. Apply necessary filtering for the editing pipeline.\n\t*\n\t* @param domElement DOM element that should have `html` set as its content.\n\t* @param html Textual representation of the HTML that will be set on `domElement`.\n\t*/\n\tsetContentOf(domElement, html) {\n\t\tif (this.renderingMode === \"data\") {\n\t\t\tdomElement.innerHTML = html;\n\t\t\treturn;\n\t\t}\n\t\tconst document = new DOMParser().parseFromString(html, \"text/html\");\n\t\tconst fragment = document.createDocumentFragment();\n\t\tconst bodyChildNodes = document.body.childNodes;\n\t\twhile (bodyChildNodes.length > 0) fragment.appendChild(bodyChildNodes[0]);\n\t\tconst treeWalker = document.createTreeWalker(fragment, NodeFilter.SHOW_ELEMENT);\n\t\tconst nodes = [];\n\t\tlet currentNode;\n\t\twhile (currentNode = treeWalker.nextNode()) nodes.push(currentNode);\n\t\tfor (const currentNode of nodes) {\n\t\t\tfor (const attributeName of currentNode.getAttributeNames()) this.setDomElementAttribute(currentNode, attributeName, currentNode.getAttribute(attributeName));\n\t\t\tconst elementName = currentNode.tagName.toLowerCase();\n\t\t\tif (this._shouldRenameElement(elementName)) {\n\t\t\t\t_logUnsafeElement(elementName);\n\t\t\t\tcurrentNode.replaceWith(this._createReplacementDomElement(elementName, currentNode));\n\t\t\t}\n\t\t}\n\t\twhile (domElement.firstChild) domElement.firstChild.remove();\n\t\tdomElement.append(fragment);\n\t}\n\t/**\n\t* Converts the view to the DOM. For all text nodes, not bound elements and document fragments new items will\n\t* be created. For bound elements and document fragments the method will return corresponding items.\n\t*\n\t* @param viewNode View node or document fragment to transform.\n\t* @param options Conversion options.\n\t* @param options.bind Determines whether new elements will be bound.\n\t* @param options.withChildren If `false`, node's and document fragment's children will not be converted.\n\t* @returns Converted node or DocumentFragment.\n\t*/\n\tviewToDom(viewNode, options = {}) {\n\t\tif (viewNode.is(\"$text\")) {\n\t\t\tconst textData = this._processDataFromViewText(viewNode);\n\t\t\treturn this._domDocument.createTextNode(textData);\n\t\t} else {\n\t\t\tconst viewElementOrFragment = viewNode;\n\t\t\tif (this.mapViewToDom(viewElementOrFragment)) if (viewElementOrFragment.getCustomProperty(\"editingPipeline:doNotReuseOnce\")) this._elementsWithTemporaryCustomProperties.add(viewElementOrFragment);\n\t\t\telse return this.mapViewToDom(viewElementOrFragment);\n\t\t\tlet domElement;\n\t\t\tif (viewElementOrFragment.is(\"documentFragment\")) {\n\t\t\t\tdomElement = this._domDocument.createDocumentFragment();\n\t\t\t\tif (options.bind) this.bindDocumentFragments(domElement, viewElementOrFragment);\n\t\t\t} else if (viewElementOrFragment.is(\"uiElement\")) {\n\t\t\t\tif (viewElementOrFragment.name === \"$comment\") domElement = this._domDocument.createComment(viewElementOrFragment.getCustomProperty(\"$rawContent\"));\n\t\t\t\telse domElement = viewElementOrFragment.render(this._domDocument, this);\n\t\t\t\tif (options.bind) this.bindElements(domElement, viewElementOrFragment);\n\t\t\t\treturn domElement;\n\t\t\t} else {\n\t\t\t\tif (this._shouldRenameElement(viewElementOrFragment.name)) {\n\t\t\t\t\t_logUnsafeElement(viewElementOrFragment.name);\n\t\t\t\t\tdomElement = this._createReplacementDomElement(viewElementOrFragment.name);\n\t\t\t\t} else if (viewElementOrFragment.hasAttribute(\"xmlns\")) domElement = this._domDocument.createElementNS(viewElementOrFragment.getAttribute(\"xmlns\"), viewElementOrFragment.name);\n\t\t\t\telse domElement = this._domDocument.createElement(viewElementOrFragment.name);\n\t\t\t\tif (viewElementOrFragment.is(\"rawElement\")) viewElementOrFragment.render(domElement, this);\n\t\t\t\tif (options.bind) this.bindElements(domElement, viewElementOrFragment);\n\t\t\t\tfor (const key of viewElementOrFragment.getAttributeKeys()) this.setDomElementAttribute(domElement, key, viewElementOrFragment.getAttribute(key), viewElementOrFragment);\n\t\t\t}\n\t\t\tif (options.withChildren !== false) for (const child of this.viewChildrenToDom(viewElementOrFragment, options)) if (domElement instanceof HTMLTemplateElement) domElement.content.appendChild(child);\n\t\t\telse domElement.appendChild(child);\n\t\t\treturn domElement;\n\t\t}\n\t}\n\t/**\n\t* Sets the attribute on a DOM element.\n\t*\n\t* **Note**: To remove the attribute, use {@link #removeDomElementAttribute}.\n\t*\n\t* @param domElement The DOM element the attribute should be set on.\n\t* @param key The name of the attribute.\n\t* @param value The value of the attribute.\n\t* @param relatedViewElement The view element related to the `domElement` (if there is any).\n\t* It helps decide whether the attribute set is unsafe. For instance, view elements created via the\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter} methods can allow certain attributes\n\t* that would normally be filtered out.\n\t*/\n\tsetDomElementAttribute(domElement, key, value, relatedViewElement) {\n\t\tconst shouldRenderAttribute = this.shouldRenderAttribute(key, value, domElement.tagName.toLowerCase()) || relatedViewElement && relatedViewElement.shouldRenderUnsafeAttribute(key);\n\t\tif (!shouldRenderAttribute) logWarning(\"domconverter-unsafe-attribute-detected\", {\n\t\t\tdomElement,\n\t\t\tkey,\n\t\t\tvalue\n\t\t});\n\t\tif (!isValidAttributeName(key)) {\n\t\t\t/**\n\t\t\t* Invalid attribute name was ignored during rendering.\n\t\t\t*\n\t\t\t* @error domconverter-invalid-attribute-detected\n\t\t\t*/\n\t\t\tlogWarning(\"domconverter-invalid-attribute-detected\", {\n\t\t\t\tdomElement,\n\t\t\t\tkey,\n\t\t\t\tvalue\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (domElement.hasAttribute(key) && !shouldRenderAttribute) domElement.removeAttribute(key);\n\t\telse if (domElement.hasAttribute(UNSAFE_ATTRIBUTE_NAME_PREFIX + key) && shouldRenderAttribute) domElement.removeAttribute(UNSAFE_ATTRIBUTE_NAME_PREFIX + key);\n\t\tdomElement.setAttribute(shouldRenderAttribute ? key : UNSAFE_ATTRIBUTE_NAME_PREFIX + key, value);\n\t}\n\t/**\n\t* Removes an attribute from a DOM element.\n\t*\n\t* **Note**: To set the attribute, use {@link #setDomElementAttribute}.\n\t*\n\t* @param domElement The DOM element the attribute should be removed from.\n\t* @param key The name of the attribute.\n\t*/\n\tremoveDomElementAttribute(domElement, key) {\n\t\tif (key == UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE) return;\n\t\tdomElement.removeAttribute(key);\n\t\tdomElement.removeAttribute(UNSAFE_ATTRIBUTE_NAME_PREFIX + key);\n\t}\n\t/**\n\t* Converts children of the view element to DOM using the\n\t* {@link module:engine/view/domconverter~ViewDomConverter#viewToDom} method.\n\t* Additionally, this method adds block {@link module:engine/view/filler filler} to the list of children, if needed.\n\t*\n\t* @param viewElement Parent view element.\n\t* @param options See {@link module:engine/view/domconverter~ViewDomConverter#viewToDom} options parameter.\n\t* @returns DOM nodes.\n\t*/\n\t*viewChildrenToDom(viewElement, options = {}) {\n\t\tconst fillerPositionOffset = viewElement.getFillerOffset && viewElement.getFillerOffset();\n\t\tlet offset = 0;\n\t\tfor (const childView of viewElement.getChildren()) {\n\t\t\tif (fillerPositionOffset === offset) yield this._getBlockFiller();\n\t\t\tconst transparentRendering = childView.is(\"element\") && !!childView.getCustomProperty(\"dataPipeline:transparentRendering\") && !first(childView.getAttributes());\n\t\t\tif (transparentRendering && this.renderingMode == \"data\") if (childView.is(\"rawElement\")) {\n\t\t\t\tconst tempElement = this._domDocument.createElement(childView.name);\n\t\t\t\tchildView.render(tempElement, this);\n\t\t\t\tyield* [...tempElement.childNodes];\n\t\t\t} else yield* this.viewChildrenToDom(childView, options);\n\t\t\telse {\n\t\t\t\tif (transparentRendering)\n /**\n\t\t\t\t* The `dataPipeline:transparentRendering` flag is supported only in the data pipeline.\n\t\t\t\t*\n\t\t\t\t* @error domconverter-transparent-rendering-unsupported-in-editing-pipeline\n\t\t\t\t*/\n\t\t\t\tlogWarning(\"domconverter-transparent-rendering-unsupported-in-editing-pipeline\", { viewElement: childView });\n\t\t\t\tyield this.viewToDom(childView, options);\n\t\t\t}\n\t\t\toffset++;\n\t\t}\n\t\tif (fillerPositionOffset === offset) yield this._getBlockFiller();\n\t}\n\t/**\n\t* Converts view {@link module:engine/view/range~ViewRange} to DOM range.\n\t* Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t*\n\t* @param viewRange View range.\n\t* @returns DOM range.\n\t*/\n\tviewRangeToDom(viewRange) {\n\t\tconst domStart = this.viewPositionToDom(viewRange.start);\n\t\tconst domEnd = this.viewPositionToDom(viewRange.end);\n\t\tconst domRange = this._domDocument.createRange();\n\t\tdomRange.setStart(domStart.parent, domStart.offset);\n\t\tdomRange.setEnd(domEnd.parent, domEnd.offset);\n\t\treturn domRange;\n\t}\n\t/**\n\t* Converts view {@link module:engine/view/position~ViewPosition} to DOM parent and offset.\n\t*\n\t* Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t* If the converted position is directly before inline filler it is moved inside the filler.\n\t*\n\t* @param viewPosition View position.\n\t* @returns DOM position or `null` if view position could not be converted to DOM.\n\t* DOM position has two properties:\n\t* * `parent` - DOM position parent.\n\t* * `offset` - DOM position offset.\n\t*/\n\tviewPositionToDom(viewPosition) {\n\t\tconst viewParent = viewPosition.parent;\n\t\tif (viewParent.is(\"$text\")) {\n\t\t\tconst domParent = this.findCorrespondingDomText(viewParent);\n\t\t\tif (!domParent) return null;\n\t\t\tlet offset = viewPosition.offset;\n\t\t\tif (startsWithFiller(domParent)) offset += 7;\n\t\t\tif (domParent.data && offset > domParent.data.length) offset = domParent.data.length;\n\t\t\treturn {\n\t\t\t\tparent: domParent,\n\t\t\t\toffset\n\t\t\t};\n\t\t} else {\n\t\t\tlet domParent, domBefore, domAfter;\n\t\t\tif (viewPosition.offset === 0) {\n\t\t\t\tdomParent = this.mapViewToDom(viewParent);\n\t\t\t\tif (!domParent) return null;\n\t\t\t\tdomAfter = domParent.childNodes[0];\n\t\t\t} else {\n\t\t\t\tconst nodeBefore = viewPosition.nodeBefore;\n\t\t\t\tdomBefore = nodeBefore.is(\"$text\") ? this.findCorrespondingDomText(nodeBefore) : this.mapViewToDom(nodeBefore);\n\t\t\t\tif (!domBefore) return null;\n\t\t\t\tdomParent = domBefore.parentNode;\n\t\t\t\tdomAfter = domBefore.nextSibling;\n\t\t\t}\n\t\t\tif (isText(domAfter) && startsWithFiller(domAfter)) return {\n\t\t\t\tparent: domAfter,\n\t\t\t\toffset: 7\n\t\t\t};\n\t\t\tconst offset = domBefore ? indexOf(domBefore) + 1 : 0;\n\t\t\treturn {\n\t\t\t\tparent: domParent,\n\t\t\t\toffset\n\t\t\t};\n\t\t}\n\t}\n\t/**\n\t* Converts DOM to view. For all text nodes, not bound elements and document fragments new items will\n\t* be created. For bound elements and document fragments function will return corresponding items. For\n\t* {@link module:engine/view/filler fillers} `null` will be returned.\n\t* For all DOM elements rendered by {@link module:engine/view/uielement~ViewUIElement} that UIElement will be returned.\n\t*\n\t* @param domNode DOM node or document fragment to transform.\n\t* @param options Conversion options.\n\t* @param options.bind Determines whether new elements will be bound. False by default.\n\t* @param options.withChildren If `true`, node's and document fragment's children will be converted too. True by default.\n\t* @param options.keepOriginalCase If `false`, node's tag name will be converted to lower case. False by default.\n\t* @param options.skipComments If `false`, comment nodes will be converted to `$comment`\n\t* {@link module:engine/view/uielement~ViewUIElement view UI elements}. False by default.\n\t* @returns Converted node or document fragment or `null` if DOM node is a {@link module:engine/view/filler filler}\n\t* or the given node is an empty text node.\n\t*/\n\tdomToView(domNode, options = {}) {\n\t\tconst inlineNodes = [];\n\t\tconst generator = this._domToView(domNode, options, inlineNodes);\n\t\tconst node = generator.next().value;\n\t\tif (!node) return null;\n\t\tgenerator.next();\n\t\tthis._processDomInlineNodes(null, inlineNodes, options);\n\t\tif (this.blockFillerMode == \"br\" && isViewBrFiller(node)) return null;\n\t\tif (node.is(\"$text\") && node.data.length == 0) return null;\n\t\treturn node;\n\t}\n\t/**\n\t* Converts children of the DOM element to view nodes using\n\t* the {@link module:engine/view/domconverter~ViewDomConverter#domToView} method.\n\t* Additionally this method omits block {@link module:engine/view/filler filler}, if it exists in the DOM parent.\n\t*\n\t* @param domElement Parent DOM element.\n\t* @param options See {@link module:engine/view/domconverter~ViewDomConverter#domToView} options parameter.\n\t* @param inlineNodes An array that will be populated with inline nodes. It's used internally for whitespace processing.\n\t* @returns View nodes.\n\t*/\n\t*domChildrenToView(domElement, options = {}, inlineNodes = []) {\n\t\tlet childNodes;\n\t\tif (domElement instanceof HTMLTemplateElement) childNodes = [...domElement.content.childNodes];\n\t\telse childNodes = [...domElement.childNodes];\n\t\tfor (let i = 0; i < childNodes.length; i++) {\n\t\t\tconst domChild = childNodes[i];\n\t\t\tconst generator = this._domToView(domChild, options, inlineNodes);\n\t\t\tconst viewChild = generator.next().value;\n\t\t\tif (viewChild !== null) {\n\t\t\t\tif (this._isBlockViewElement(viewChild)) this._processDomInlineNodes(domElement, inlineNodes, options);\n\t\t\t\tif (!(this.blockFillerMode == \"br\" && isViewBrFiller(viewChild))) yield viewChild;\n\t\t\t\tgenerator.next();\n\t\t\t}\n\t\t}\n\t\tthis._processDomInlineNodes(domElement, inlineNodes, options);\n\t}\n\t/**\n\t* Converts DOM selection to view {@link module:engine/view/selection~ViewSelection}.\n\t* Ranges which cannot be converted will be omitted.\n\t*\n\t* @param domSelection DOM selection.\n\t* @returns View selection.\n\t*/\n\tdomSelectionToView(domSelection) {\n\t\tif (isGeckoRestrictedDomSelection(domSelection)) return new ViewSelection([]);\n\t\tif (domSelection.rangeCount === 1) {\n\t\t\tlet container = domSelection.getRangeAt(0).startContainer;\n\t\t\tif (isText(container)) container = container.parentNode;\n\t\t\tconst viewSelection = this.fakeSelectionToView(container);\n\t\t\tif (viewSelection) return viewSelection;\n\t\t}\n\t\tconst isBackward = this.isDomSelectionBackward(domSelection);\n\t\tconst viewRanges = [];\n\t\tfor (let i = 0; i < domSelection.rangeCount; i++) {\n\t\t\tconst domRange = domSelection.getRangeAt(i);\n\t\t\tconst viewRange = this.domRangeToView(domRange);\n\t\t\tif (viewRange) viewRanges.push(viewRange);\n\t\t}\n\t\treturn new ViewSelection(viewRanges, { backward: isBackward });\n\t}\n\t/**\n\t* Converts DOM Range to view {@link module:engine/view/range~ViewRange}.\n\t* If the start or end position cannot be converted `null` is returned.\n\t*\n\t* @param domRange DOM range.\n\t* @returns View range.\n\t*/\n\tdomRangeToView(domRange) {\n\t\tconst viewStart = this.domPositionToView(domRange.startContainer, domRange.startOffset);\n\t\tconst viewEnd = this.domPositionToView(domRange.endContainer, domRange.endOffset);\n\t\tif (viewStart && viewEnd) return new ViewRange(viewStart, viewEnd);\n\t\treturn null;\n\t}\n\t/**\n\t* Converts DOM parent and offset to view {@link module:engine/view/position~ViewPosition}.\n\t*\n\t* If the position is inside a {@link module:engine/view/filler filler} which has no corresponding view node,\n\t* position of the filler will be converted and returned.\n\t*\n\t* If the position is inside DOM element rendered by {@link module:engine/view/uielement~ViewUIElement}\n\t* that position will be converted to view position before that UIElement.\n\t*\n\t* If structures are too different and it is not possible to find corresponding position then `null` will be returned.\n\t*\n\t* @param domParent DOM position parent.\n\t* @param domOffset DOM position offset. You can skip it when converting the inline filler node.\n\t* @returns View position.\n\t*/\n\tdomPositionToView(domParent, domOffset = 0) {\n\t\tif (this.isBlockFiller(domParent)) return this.domPositionToView(domParent.parentNode, indexOf(domParent));\n\t\tconst viewElement = this.mapDomToView(domParent);\n\t\tif (viewElement && (viewElement.is(\"uiElement\") || viewElement.is(\"rawElement\"))) return ViewPosition._createBefore(viewElement);\n\t\tif (isText(domParent)) {\n\t\t\tif (isInlineFiller(domParent)) return this.domPositionToView(domParent.parentNode, indexOf(domParent));\n\t\t\tconst viewParent = this.findCorrespondingViewText(domParent);\n\t\t\tlet offset = domOffset;\n\t\t\tif (!viewParent) return null;\n\t\t\tif (startsWithFiller(domParent)) {\n\t\t\t\toffset -= 7;\n\t\t\t\toffset = offset < 0 ? 0 : offset;\n\t\t\t}\n\t\t\treturn new ViewPosition(viewParent, offset);\n\t\t} else {\n\t\t\tif (domOffset === 0) {\n\t\t\t\tconst viewParent = this.mapDomToView(domParent);\n\t\t\t\tif (viewParent) return new ViewPosition(viewParent, 0);\n\t\t\t} else {\n\t\t\t\tconst domBefore = domParent.childNodes[domOffset - 1];\n\t\t\t\tif (isText(domBefore) && isInlineFiller(domBefore) || domBefore && this.isBlockFiller(domBefore)) return this.domPositionToView(domBefore.parentNode, indexOf(domBefore));\n\t\t\t\tconst viewBefore = isText(domBefore) ? this.findCorrespondingViewText(domBefore) : this.mapDomToView(domBefore);\n\t\t\t\tif (viewBefore && viewBefore.parent) return new ViewPosition(viewBefore.parent, viewBefore.index + 1);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t* Returns corresponding view {@link module:engine/view/element~ViewElement Element} or\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment} for provided DOM element or\n\t* document fragment. If there is no view item {@link module:engine/view/domconverter~ViewDomConverter#bindElements bound}\n\t* to the given DOM - `undefined` is returned.\n\t*\n\t* For all DOM elements rendered by a {@link module:engine/view/uielement~ViewUIElement} or\n\t* a {@link module:engine/view/rawelement~ViewRawElement}, the parent `UIElement` or `RawElement` will be returned.\n\t*\n\t* @param domElementOrDocumentFragment DOM element or document fragment.\n\t* @returns Corresponding view element, document fragment or `undefined` if no element was bound.\n\t*/\n\tmapDomToView(domElementOrDocumentFragment) {\n\t\treturn this.getHostViewElement(domElementOrDocumentFragment) || this._domToViewMapping.get(domElementOrDocumentFragment);\n\t}\n\t/**\n\t* Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~ViewDomConverter#bindElements bound},\n\t* corresponding text node is returned based on the sibling or parent.\n\t*\n\t* If the directly previous sibling is a {@link module:engine/view/domconverter~ViewDomConverter#bindElements bound} element, it is used\n\t* to find the corresponding text node.\n\t*\n\t* If this is a first child in the parent and the parent is a\n\t* {@link module:engine/view/domconverter~ViewDomConverter#bindElements bound}\n\t* element, it is used to find the corresponding text node.\n\t*\n\t* For all text nodes rendered by a {@link module:engine/view/uielement~ViewUIElement} or\n\t* a {@link module:engine/view/rawelement~ViewRawElement}, the parent `UIElement` or `RawElement` will be returned.\n\t*\n\t* Otherwise `null` is returned.\n\t*\n\t* Note that for the block or inline {@link module:engine/view/filler filler} this method returns `null`.\n\t*\n\t* @param domText DOM text node.\n\t* @returns Corresponding view text node or `null`, if it was not possible to find a corresponding node.\n\t*/\n\tfindCorrespondingViewText(domText) {\n\t\tif (isInlineFiller(domText)) return null;\n\t\tconst hostElement = this.getHostViewElement(domText);\n\t\tif (hostElement) return hostElement;\n\t\tconst previousSibling = domText.previousSibling;\n\t\tif (previousSibling) {\n\t\t\tif (!this.isElement(previousSibling)) return null;\n\t\t\tconst viewElement = this.mapDomToView(previousSibling);\n\t\t\tif (viewElement) {\n\t\t\t\tconst nextSibling = viewElement.nextSibling;\n\t\t\t\tif (nextSibling instanceof ViewText) return nextSibling;\n\t\t\t\telse return null;\n\t\t\t}\n\t\t} else {\n\t\t\tconst viewElement = this.mapDomToView(domText.parentNode);\n\t\t\tif (viewElement) {\n\t\t\t\tconst firstChild = viewElement.getChild(0);\n\t\t\t\tif (firstChild instanceof ViewText) return firstChild;\n\t\t\t\telse return null;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\tmapViewToDom(documentFragmentOrElement) {\n\t\treturn this._viewToDomMapping.get(documentFragmentOrElement);\n\t}\n\t/**\n\t* Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~ViewDomConverter#bindElements bound},\n\t* corresponding text node is returned based on the sibling or parent.\n\t*\n\t* If the directly previous sibling is a {@link module:engine/view/domconverter~ViewDomConverter#bindElements bound} element, it is used\n\t* to find the corresponding text node.\n\t*\n\t* If this is a first child in the parent and the parent is a\n\t* {@link module:engine/view/domconverter~ViewDomConverter#bindElements bound}\n\t* element, it is used to find the corresponding text node.\n\t*\n\t* Otherwise `null` is returned.\n\t*\n\t* @param viewText View text node.\n\t* @returns Corresponding DOM text node or `null`, if it was not possible to find a corresponding node.\n\t*/\n\tfindCorrespondingDomText(viewText) {\n\t\tconst previousSibling = viewText.previousSibling;\n\t\tif (previousSibling && this.mapViewToDom(previousSibling)) return this.mapViewToDom(previousSibling).nextSibling;\n\t\tif (!previousSibling && viewText.parent && this.mapViewToDom(viewText.parent)) return this.mapViewToDom(viewText.parent).childNodes[0];\n\t\treturn null;\n\t}\n\t/**\n\t* Focuses DOM editable that is corresponding to provided {@link module:engine/view/editableelement~ViewEditableElement}.\n\t*/\n\tfocus(viewEditable) {\n\t\tconst domEditable = this.mapViewToDom(viewEditable);\n\t\tif (!domEditable || domEditable.ownerDocument.activeElement === domEditable) return;\n\t\tconst { scrollX, scrollY } = global.window;\n\t\tconst scrollPositions = [];\n\t\tforEachDomElementAncestor(domEditable, (node) => {\n\t\t\tconst { scrollLeft, scrollTop } = node;\n\t\t\tscrollPositions.push([scrollLeft, scrollTop]);\n\t\t});\n\t\tdomEditable.focus({ preventScroll: true });\n\t\tforEachDomElementAncestor(domEditable, (node) => {\n\t\t\tconst [scrollLeft, scrollTop] = scrollPositions.shift();\n\t\t\tnode.scrollLeft = scrollLeft;\n\t\t\tnode.scrollTop = scrollTop;\n\t\t});\n\t\tglobal.window.scrollTo(scrollX, scrollY);\n\t}\n\t/**\n\t* Remove DOM selection from blurred editable, so it won't interfere with clicking on dropdowns (especially on iOS).\n\t*\n\t* @internal\n\t*/\n\t_clearDomSelection() {\n\t\tconst domEditable = this.mapViewToDom(this.document.selection.editableElement);\n\t\tif (!domEditable) return;\n\t\tconst domSelection = domEditable.ownerDocument.defaultView.getSelection();\n\t\tconst newViewSelection = this.domSelectionToView(domSelection);\n\t\tif (newViewSelection && newViewSelection.rangeCount > 0) domSelection.removeAllRanges();\n\t}\n\t/**\n\t* Returns `true` when `node.nodeType` equals `Node.ELEMENT_NODE`.\n\t*\n\t* @param node Node to check.\n\t*/\n\tisElement(node) {\n\t\treturn node && node.nodeType == Node.ELEMENT_NODE;\n\t}\n\t/**\n\t* Returns `true` when `node.nodeType` equals `Node.DOCUMENT_FRAGMENT_NODE`.\n\t*\n\t* @param node Node to check.\n\t*/\n\tisDocumentFragment(node) {\n\t\treturn node && node.nodeType == Node.DOCUMENT_FRAGMENT_NODE;\n\t}\n\t/**\n\t* Checks if the node is an instance of the block filler for this DOM converter.\n\t*\n\t* ```ts\n\t* const converter = new ViewDomConverter( viewDocument, { blockFillerMode: 'br' } );\n\t*\n\t* converter.isBlockFiller( BR_FILLER( document ) ); // true\n\t* converter.isBlockFiller( NBSP_FILLER( document ) ); // false\n\t* ```\n\t*\n\t* **Note:**: For the `'nbsp'` mode the method also checks context of a node so it cannot be a detached node.\n\t*\n\t* **Note:** A special case in the `'nbsp'` mode exists where the `<br>` in `<p><br></p>` is treated as a block filler.\n\t*\n\t* @param domNode DOM node to check.\n\t* @returns True if a node is considered a block filler for given mode.\n\t*/\n\tisBlockFiller(domNode) {\n\t\tif (this.blockFillerMode == \"br\") return domNode.isEqualNode(BR_FILLER_REF);\n\t\tif (isOnlyBrInBlock(domNode, this.blockElements)) return true;\n\t\treturn domNode.isEqualNode(MARKED_NBSP_FILLER_REF) || isNbspBlockFiller(domNode, this.blockElements);\n\t}\n\t/**\n\t* Returns `true` if given selection is a backward selection, that is, if it's `focus` is before `anchor`.\n\t*\n\t* @param selection Selection instance to check.\n\t*/\n\tisDomSelectionBackward(selection) {\n\t\tif (selection.isCollapsed) return false;\n\t\tconst range = this._domDocument.createRange();\n\t\ttry {\n\t\t\trange.setStart(selection.anchorNode, selection.anchorOffset);\n\t\t\trange.setEnd(selection.focusNode, selection.focusOffset);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t\tconst backward = range.collapsed;\n\t\trange.detach();\n\t\treturn backward;\n\t}\n\t/**\n\t* Returns a parent {@link module:engine/view/uielement~ViewUIElement} or {@link module:engine/view/rawelement~ViewRawElement}\n\t* that hosts the provided DOM node. Returns `null` if there is no such parent.\n\t*/\n\tgetHostViewElement(domNode) {\n\t\tconst ancestors = getAncestors(domNode);\n\t\tancestors.pop();\n\t\twhile (ancestors.length) {\n\t\t\tconst domNode = ancestors.pop();\n\t\t\tconst viewNode = this._domToViewMapping.get(domNode);\n\t\t\tif (viewNode && (viewNode.is(\"uiElement\") || viewNode.is(\"rawElement\"))) return viewNode;\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Checks if the given selection's boundaries are at correct places.\n\t*\n\t* The following places are considered as incorrect for selection boundaries:\n\t*\n\t* * before or in the middle of an inline filler sequence,\n\t* * inside a DOM element which represents {@link module:engine/view/uielement~ViewUIElement a view UI element},\n\t* * inside a DOM element which represents {@link module:engine/view/rawelement~ViewRawElement a view raw element}.\n\t*\n\t* @param domSelection The DOM selection object to be checked.\n\t* @returns `true` if the given selection is at a correct place, `false` otherwise.\n\t*/\n\tisDomSelectionCorrect(domSelection) {\n\t\treturn this._isDomSelectionPositionCorrect(domSelection.anchorNode, domSelection.anchorOffset) && this._isDomSelectionPositionCorrect(domSelection.focusNode, domSelection.focusOffset);\n\t}\n\t/**\n\t* Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t* and not processed during the conversion from DOM nodes to view elements.\n\t*\n\t* This is affecting how {@link module:engine/view/domconverter~ViewDomConverter#domToView} and\n\t* {@link module:engine/view/domconverter~ViewDomConverter#domChildrenToView} process DOM nodes.\n\t*\n\t* The raw data can be later accessed by a\n\t* {@link module:engine/view/element~ViewElement#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t*\n\t* @param pattern Pattern matching a view element whose content should\n\t* be treated as raw data.\n\t*/\n\tregisterRawContentMatcher(pattern) {\n\t\tthis._rawContentElementMatcher.add(pattern);\n\t}\n\t/**\n\t* Registers a {@link module:engine/view/matcher~MatcherPattern} for inline object view elements.\n\t*\n\t* This is affecting how {@link module:engine/view/domconverter~ViewDomConverter#domToView} and\n\t* {@link module:engine/view/domconverter~ViewDomConverter#domChildrenToView} process DOM nodes.\n\t*\n\t* This is an extension of a simple {@link #inlineObjectElements} array of element names.\n\t*\n\t* @param pattern Pattern matching a view element which should be treated as an inline object.\n\t*/\n\tregisterInlineObjectMatcher(pattern) {\n\t\tthis._inlineObjectElementMatcher.add(pattern);\n\t}\n\t/**\n\t* Clear temporary custom properties.\n\t*\n\t* @internal\n\t*/\n\t_clearTemporaryCustomProperties() {\n\t\tfor (const element of this._elementsWithTemporaryCustomProperties) element._removeCustomProperty(\"editingPipeline:doNotReuseOnce\");\n\t\tthis._elementsWithTemporaryCustomProperties.clear();\n\t}\n\t/**\n\t* Returns the block {@link module:engine/view/filler filler} node based on the current {@link #blockFillerMode} setting.\n\t*/\n\t_getBlockFiller() {\n\t\tswitch (this.blockFillerMode) {\n\t\t\tcase \"nbsp\": return NBSP_FILLER(this._domDocument);\n\t\t\tcase \"markedNbsp\": return MARKED_NBSP_FILLER(this._domDocument);\n\t\t\tcase \"br\": return BR_FILLER(this._domDocument);\n\t\t}\n\t}\n\t/**\n\t* Checks if the given DOM position is a correct place for selection boundary. See {@link #isDomSelectionCorrect}.\n\t*\n\t* @param domParent Position parent.\n\t* @param offset Position offset.\n\t* @returns `true` if given position is at a correct place for selection boundary, `false` otherwise.\n\t*/\n\t_isDomSelectionPositionCorrect(domParent, offset) {\n\t\tif (isText(domParent) && startsWithFiller(domParent) && offset < 7) return false;\n\t\tif (this.isElement(domParent) && startsWithFiller(domParent.childNodes[offset])) return false;\n\t\tconst viewParent = this.mapDomToView(domParent);\n\t\tif (viewParent && (viewParent.is(\"uiElement\") || viewParent.is(\"rawElement\"))) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Internal generator for {@link #domToView}. Also used by {@link #domChildrenToView}.\n\t* Separates DOM nodes conversion from whitespaces processing.\n\t*\n\t* @param domNode DOM node or document fragment to transform.\n\t* @param inlineNodes An array of recently encountered inline nodes truncated to the block element boundaries.\n\t* Used later to process whitespaces.\n\t*/\n\t*_domToView(domNode, options, inlineNodes) {\n\t\tif (this.blockFillerMode != \"br\" && isOnlyBrInBlock(domNode, this.blockElements)) return null;\n\t\tconst hostElement = this.getHostViewElement(domNode);\n\t\tif (hostElement) return hostElement;\n\t\tif (isComment(domNode) && options.skipComments) return null;\n\t\tif (isText(domNode)) if (isInlineFiller(domNode)) return null;\n\t\telse {\n\t\t\tconst textData = domNode.data;\n\t\t\tif (textData === \"\") return null;\n\t\t\tconst textNode = new ViewText(this.document, textData);\n\t\t\tinlineNodes.push(textNode);\n\t\t\treturn textNode;\n\t\t}\n\t\telse {\n\t\t\tlet viewElement = this.mapDomToView(domNode);\n\t\t\tif (viewElement) {\n\t\t\t\tif (this._isInlineObjectElement(viewElement)) inlineNodes.push(viewElement);\n\t\t\t\treturn viewElement;\n\t\t\t}\n\t\t\tif (this.isDocumentFragment(domNode)) {\n\t\t\t\tviewElement = new ViewDocumentFragment(this.document);\n\t\t\t\tif (options.bind) this.bindDocumentFragments(domNode, viewElement);\n\t\t\t} else {\n\t\t\t\tviewElement = this._createViewElement(domNode, options);\n\t\t\t\tif (options.bind) this.bindElements(domNode, viewElement);\n\t\t\t\tconst attrs = domNode.attributes;\n\t\t\t\tif (attrs) for (let l = attrs.length, i = 0; i < l; i++) viewElement._setAttribute(attrs[i].name, attrs[i].value);\n\t\t\t\tif (this._isViewElementWithRawContent(viewElement, options)) {\n\t\t\t\t\tviewElement._setCustomProperty(\"$rawContent\", domNode.innerHTML);\n\t\t\t\t\tif (!this._isBlockViewElement(viewElement)) inlineNodes.push(viewElement);\n\t\t\t\t\treturn viewElement;\n\t\t\t\t}\n\t\t\t\tif (isComment(domNode)) {\n\t\t\t\t\tviewElement._setCustomProperty(\"$rawContent\", domNode.data);\n\t\t\t\t\treturn viewElement;\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield viewElement;\n\t\t\tconst nestedInlineNodes = [];\n\t\t\tif (options.withChildren !== false) for (const child of this.domChildrenToView(domNode, options, nestedInlineNodes)) viewElement._appendChild(child);\n\t\t\tif (this._isInlineObjectElement(viewElement)) {\n\t\t\t\tinlineNodes.push(viewElement);\n\t\t\t\tthis._processDomInlineNodes(null, nestedInlineNodes, options);\n\t\t\t} else for (const inlineNode of nestedInlineNodes) inlineNodes.push(inlineNode);\n\t\t}\n\t}\n\t/**\n\t* Internal helper that walks the list of inline view nodes already generated from DOM nodes\n\t* and handles whitespaces and NBSPs.\n\t*\n\t* @param domParent The DOM parent of the given inline nodes. This should be a document fragment or\n\t* a block element to whitespace processing start cleaning.\n\t* @param inlineNodes An array of recently encountered inline nodes truncated to the block element boundaries.\n\t*/\n\t_processDomInlineNodes(domParent, inlineNodes, options) {\n\t\tif (!inlineNodes.length) return;\n\t\tif (domParent && !this.isDocumentFragment(domParent) && !this._isBlockDomElement(domParent)) return;\n\t\tlet prevNodeEndsWithSpace = false;\n\t\tfor (let i = 0; i < inlineNodes.length; i++) {\n\t\t\tconst node = inlineNodes[i];\n\t\t\tif (!node.is(\"$text\")) {\n\t\t\t\tprevNodeEndsWithSpace = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet data;\n\t\t\tlet nodeEndsWithSpace = false;\n\t\t\tif (this._isPreFormatted(node)) data = getDataWithoutFiller(node.data);\n\t\t\telse {\n\t\t\t\tdata = node.data.replace(/[ \\n\\t\\r]{1,}/g, \" \");\n\t\t\t\tnodeEndsWithSpace = /[^\\S\\u00A0]/.test(data.charAt(data.length - 1));\n\t\t\t\tconst prevNode = i > 0 ? inlineNodes[i - 1] : null;\n\t\t\t\tconst nextNode = i + 1 < inlineNodes.length ? inlineNodes[i + 1] : null;\n\t\t\t\tconst shouldLeftTrim = !prevNode || prevNode.is(\"element\") && prevNode.name == \"br\" || prevNodeEndsWithSpace;\n\t\t\t\tconst shouldRightTrim = nextNode ? false : !startsWithFiller(node.data);\n\t\t\t\tif (options.withChildren !== false) {\n\t\t\t\t\tif (shouldLeftTrim) data = data.replace(/^ /, \"\");\n\t\t\t\t\tif (shouldRightTrim) data = data.replace(/ $/, \"\");\n\t\t\t\t}\n\t\t\t\tdata = getDataWithoutFiller(data);\n\t\t\t\tif (this.blockFillerMode != \"br\" && node.parent) {\n\t\t\t\t\tif (isViewMarkedNbspFiller(node.parent, data)) {\n\t\t\t\t\t\tdata = \"\";\n\t\t\t\t\t\tif (node.parent.parent) {\n\t\t\t\t\t\t\tnode.parent.parent._setCustomProperty(\"$hasBlockFiller\", true);\n\t\t\t\t\t\t\tnode.parent._remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (isViewNbspFiller(node.parent, data, this.blockElements)) {\n\t\t\t\t\t\tdata = \"\";\n\t\t\t\t\t\tnode.parent._setCustomProperty(\"$hasBlockFiller\", true);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdata = data.replace(/ \\u00A0/g, \" \");\n\t\t\t\tconst isNextNodeInlineObjectElement = nextNode && nextNode.is(\"element\") && nextNode.name != \"br\";\n\t\t\t\tconst isNextNodeStartingWithSpace = nextNode && nextNode.is(\"$text\") && nextNode.data.charAt(0) == \" \";\n\t\t\t\tif (/[ \\u00A0]\\u00A0$/.test(data) || !nextNode || isNextNodeInlineObjectElement || isNextNodeStartingWithSpace) data = data.replace(/\\u00A0$/, \" \");\n\t\t\t\tif (shouldLeftTrim || prevNode && prevNode.is(\"element\") && prevNode.name != \"br\") data = data.replace(/^\\u00A0/, \" \");\n\t\t\t}\n\t\t\tif (data.length == 0 && node.parent) {\n\t\t\t\tnode._remove();\n\t\t\t\tinlineNodes.splice(i, 1);\n\t\t\t\ti--;\n\t\t\t} else {\n\t\t\t\tnode._data = data;\n\t\t\t\tprevNodeEndsWithSpace = nodeEndsWithSpace;\n\t\t\t}\n\t\t}\n\t\tinlineNodes.length = 0;\n\t}\n\t/**\n\t* Takes text data from a given {@link module:engine/view/text~ViewText#data} and processes it so\n\t* it is correctly displayed in the DOM.\n\t*\n\t* Following changes are done:\n\t*\n\t* * a space at the beginning is changed to `&nbsp;` if this is the first text node in its container\n\t* element or if a previous text node ends with a space character,\n\t* * space at the end of the text node is changed to `&nbsp;` if there are two spaces at the end of a node or if next node\n\t* starts with a space or if it is the last text node in its container,\n\t* * remaining spaces are replaced to a chain of spaces and `&nbsp;` (e.g. `'x x'` becomes `'x &nbsp; x'`).\n\t*\n\t* Content of {@link #preElements} is not processed.\n\t*\n\t* @param node View text node to process.\n\t* @returns Processed text data.\n\t*/\n\t_processDataFromViewText(node) {\n\t\tlet data = node.data;\n\t\tif (this._isPreFormatted(node)) return data;\n\t\tif (data.charAt(0) == \" \") {\n\t\t\tconst prevNode = this._getTouchingInlineViewNode(node, false);\n\t\t\tif (prevNode && prevNode.is(\"$textProxy\") && this._nodeEndsWithSpace(prevNode) || !prevNode) data = \"\\xA0\" + data.substr(1);\n\t\t}\n\t\tif (data.charAt(data.length - 1) == \" \") {\n\t\t\tconst nextNode = this._getTouchingInlineViewNode(node, true);\n\t\t\tconst nextStartsWithSpace = nextNode && nextNode.is(\"$textProxy\") && nextNode.data.charAt(0) == \" \";\n\t\t\tif (data.charAt(data.length - 2) == \" \" || !nextNode || nextStartsWithSpace) data = data.substr(0, data.length - 1) + \"\\xA0\";\n\t\t}\n\t\treturn data.replace(/ {2}/g, \" \\xA0\");\n\t}\n\t/**\n\t* Checks whether given node ends with a space character after changing appropriate space characters to `&nbsp;`s.\n\t*\n\t* @param node Node to check.\n\t* @returns `true` if given `node` ends with space, `false` otherwise.\n\t*/\n\t_nodeEndsWithSpace(node) {\n\t\tif (this._isPreFormatted(node)) return false;\n\t\tconst data = this._processDataFromViewText(node);\n\t\treturn data.charAt(data.length - 1) == \" \";\n\t}\n\t/**\n\t* Checks whether given text contains preformatted white space. This is the case if\n\t* * any of node ancestors has a name which is in `preElements` array, or\n\t* * the closest ancestor that has the `white-space` CSS property sets it to a value that preserves spaces\n\t*\n\t* @param node Node to check\n\t* @returns `true` if given node contains preformatted white space, `false` otherwise.\n\t*/\n\t_isPreFormatted(node) {\n\t\tif (_hasViewParentOfType(node, this.preElements)) return true;\n\t\tfor (const ancestor of node.getAncestors({ parentFirst: true })) {\n\t\t\tif (!ancestor.is(\"element\") || !ancestor.hasStyle(\"white-space\") || ancestor.getStyle(\"white-space\") === \"inherit\") continue;\n\t\t\treturn [\n\t\t\t\t\"pre\",\n\t\t\t\t\"pre-wrap\",\n\t\t\t\t\"break-spaces\"\n\t\t\t].includes(ancestor.getStyle(\"white-space\"));\n\t\t}\n\t\treturn false;\n\t}\n\t/**\n\t* Helper function. For given {@link module:engine/view/text~ViewText view text node}, it finds previous or next sibling\n\t* that is contained in the same container element. If there is no such sibling, `null` is returned.\n\t*\n\t* @param node Reference node.\n\t* @returns Touching text node, an inline object\n\t* or `null` if there is no next or previous touching text node.\n\t*/\n\t_getTouchingInlineViewNode(node, getNext) {\n\t\tconst treeWalker = new ViewTreeWalker({\n\t\t\tstartPosition: getNext ? ViewPosition._createAfter(node) : ViewPosition._createBefore(node),\n\t\t\tdirection: getNext ? \"forward\" : \"backward\"\n\t\t});\n\t\tfor (const { item } of treeWalker) if (item.is(\"$textProxy\")) return item;\n\t\telse if (item.is(\"element\") && item.getCustomProperty(\"dataPipeline:transparentRendering\")) continue;\n\t\telse if (item.is(\"element\", \"br\")) return null;\n\t\telse if (this._isInlineObjectElement(item)) return item;\n\t\telse if (item.is(\"containerElement\") || this._isBlockViewElement(item)) return null;\n\t\treturn null;\n\t}\n\t/**\n\t* Returns `true` if a DOM node belongs to {@link #blockElements}. `false` otherwise.\n\t*/\n\t_isBlockDomElement(node) {\n\t\treturn this.isElement(node) && this.blockElements.includes(node.tagName.toLowerCase());\n\t}\n\t/**\n\t* Returns `true` if a view node belongs to {@link #blockElements}. `false` otherwise.\n\t*/\n\t_isBlockViewElement(node) {\n\t\treturn node.is(\"element\") && this.blockElements.includes(node.name);\n\t}\n\t/**\n\t* Returns `true` if a DOM node belongs to {@link #inlineObjectElements}. `false` otherwise.\n\t*/\n\t_isInlineObjectElement(node) {\n\t\tif (!node.is(\"element\")) return false;\n\t\treturn node.name == \"br\" || this.inlineObjectElements.includes(node.name) || !!this._inlineObjectElementMatcher.match(node);\n\t}\n\t/**\n\t* Creates view element basing on the node type.\n\t*\n\t* @param node DOM node to check.\n\t* @param options Conversion options. See {@link module:engine/view/domconverter~ViewDomConverter#domToView} options parameter.\n\t*/\n\t_createViewElement(node, options) {\n\t\tif (isComment(node)) return new ViewUIElement(this.document, \"$comment\");\n\t\tconst viewName = options.keepOriginalCase ? node.tagName : node.tagName.toLowerCase();\n\t\treturn new ViewElement(this.document, viewName);\n\t}\n\t/**\n\t* Checks if view element's content should be treated as a raw data.\n\t*\n\t* @param viewElement View element to check.\n\t* @param options Conversion options. See {@link module:engine/view/domconverter~ViewDomConverter#domToView} options parameter.\n\t*/\n\t_isViewElementWithRawContent(viewElement, options) {\n\t\treturn options.withChildren !== false && viewElement.is(\"element\") && !!this._rawContentElementMatcher.match(viewElement);\n\t}\n\t/**\n\t* Checks whether a given element name should be renamed in a current rendering mode.\n\t*\n\t* @param elementName The name of view element.\n\t*/\n\t_shouldRenameElement(elementName) {\n\t\tconst name = elementName.toLowerCase();\n\t\treturn this.renderingMode === \"editing\" && this.unsafeElements.includes(name);\n\t}\n\t/**\n\t* Return a <span> element with a special attribute holding the name of the original element.\n\t* Optionally, copy all the attributes of the original element if that element is provided.\n\t*\n\t* @param elementName The name of view element.\n\t* @param originalDomElement The original DOM element to copy attributes and content from.\n\t*/\n\t_createReplacementDomElement(elementName, originalDomElement) {\n\t\tconst newDomElement = this._domDocument.createElement(\"span\");\n\t\tnewDomElement.setAttribute(UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE, elementName);\n\t\tif (originalDomElement) {\n\t\t\twhile (originalDomElement.firstChild) newDomElement.appendChild(originalDomElement.firstChild);\n\t\t\tfor (const attributeName of originalDomElement.getAttributeNames()) newDomElement.setAttribute(attributeName, originalDomElement.getAttribute(attributeName));\n\t\t}\n\t\treturn newDomElement;\n\t}\n};\n/**\n* Helper function.\n* Used to check if given native `Element` or `Text` node has parent with tag name from `types` array.\n*\n* @returns`true` if such parent exists or `false` if it does not.\n*/\nfunction _hasViewParentOfType(node, types) {\n\treturn node.getAncestors().some((parent) => parent.is(\"element\") && types.includes(parent.name));\n}\n/**\n* A helper that executes given callback for each DOM node's ancestor, starting from the given node\n* and ending in document#documentElement.\n*\n* @param callback A callback to be executed for each ancestor.\n*/\nfunction forEachDomElementAncestor(element, callback) {\n\tlet node = element;\n\twhile (node) {\n\t\tcallback(node);\n\t\tnode = node.parentElement;\n\t}\n}\n/**\n* Checks if given DOM node is a nbsp block filler.\n*\n* A &nbsp; is a block filler only if it is a single child of a block element.\n*\n* @param domNode DOM node.\n*/\nfunction isNbspBlockFiller(domNode, blockElements) {\n\treturn domNode.isEqualNode(NBSP_FILLER_REF) && hasBlockParent(domNode, blockElements) && domNode.parentNode.childNodes.length === 1;\n}\n/**\n* Checks if domNode has block parent.\n*\n* @param domNode DOM node.\n*/\nfunction hasBlockParent(domNode, blockElements) {\n\tconst parent = domNode.parentNode;\n\treturn !!parent && !!parent.tagName && blockElements.includes(parent.tagName.toLowerCase());\n}\n/**\n* Checks if given view node is a nbsp block filler.\n*\n* A &nbsp; is a block filler only if it is a single child of a block element.\n*/\nfunction isViewNbspFiller(parent, data, blockElements) {\n\treturn data == \"\\xA0\" && parent && parent.is(\"element\") && parent.childCount == 1 && blockElements.includes(parent.name);\n}\n/**\n* Checks if given view node is a marked-nbsp block filler.\n*\n* A &nbsp; is a block filler only if it is wrapped in `<span data-cke-filler=\"true\">` element.\n*/\nfunction isViewMarkedNbspFiller(parent, data) {\n\treturn data == \"\\xA0\" && parent && parent.is(\"element\", \"span\") && parent.childCount == 1 && parent.hasAttribute(\"data-cke-filler\");\n}\n/**\n* Checks if given view node is a br block filler.\n*\n* A <br> is a block filler only if it has data-cke-filler attribute set.\n*/\nfunction isViewBrFiller(node) {\n\treturn node.is(\"element\", \"br\") && node.hasAttribute(\"data-cke-filler\");\n}\n/**\n* Special case for `<p><br></p>` in which `<br>` should be treated as filler even when we are not in the 'br' mode.\n*/\nfunction isOnlyBrInBlock(domNode, blockElements) {\n\treturn domNode.tagName === \"BR\" && hasBlockParent(domNode, blockElements) && domNode.parentNode.childNodes.length === 1;\n}\n/**\n* Log to console the information about element that was replaced.\n* Check UNSAFE_ELEMENTS for all recognized unsafe elements.\n*\n* @param elementName The name of the view element.\n*/\nfunction _logUnsafeElement(elementName) {\n\tif (elementName === \"script\") logWarning(\"domconverter-unsafe-script-element-detected\");\n\tif (elementName === \"style\") logWarning(\"domconverter-unsafe-style-element-detected\");\n}\n/**\n* In certain cases, Firefox mysteriously assigns so called \"restricted objects\" to native DOM Range properties.\n* Any attempt at accessing restricted object's properties causes errors.\n* See: https://github.com/ckeditor/ckeditor5/issues/9635.\n*/\nfunction isGeckoRestrictedDomSelection(domSelection) {\n\tif (!env.isGecko) return false;\n\tif (!domSelection.rangeCount) return false;\n\tconst container = domSelection.getRangeAt(0).startContainer;\n\ttry {\n\t\tObject.prototype.toString.call(container);\n\t} catch {\n\t\treturn true;\n\t}\n\treturn false;\n}\n/**\n* While rendering the editor content, the {@link module:engine/view/domconverter~ViewDomConverter} detected a `<script>` element that may\n* disrupt the editing experience. To avoid this, the `<script>` element was replaced with `<span data-ck-unsafe-element=\"script\"></span>`.\n*\n* @error domconverter-unsafe-script-element-detected\n*/\n/**\n* While rendering the editor content, the\n* {@link module:engine/view/domconverter~ViewDomConverter} detected a `<style>` element that may affect\n* the editing experience. To avoid this, the `<style>` element was replaced with `<span data-ck-unsafe-element=\"style\"></span>`.\n*\n* @error domconverter-unsafe-style-element-detected\n*/\n/**\n* The {@link module:engine/view/domconverter~ViewDomConverter} detected an interactive attribute in the\n* {@glink framework/architecture/editing-engine#editing-pipeline editing pipeline}. For the best\n* editing experience, the attribute was renamed to `data-ck-unsafe-attribute-[original attribute name]`.\n*\n* If you are the author of the plugin that generated this attribute and you want it to be preserved\n* in the editing pipeline, you can configure this when creating the element\n* using {@link module:engine/view/downcastwriter~ViewDowncastWriter} during the\n* {@glink framework/architecture/editing-engine#conversion model–view conversion}. Methods such as\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createContainerElement},\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createAttributeElement}, or\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createEmptyElement}\n* accept an option that will disable filtering of specific attributes:\n*\n* ```ts\n* const paragraph = writer.createContainerElement( 'p',\n* \t{\n* \t\tclass: 'clickable-paragraph',\n* \t\tonclick: 'alert( \"Paragraph clicked!\" )'\n* \t},\n* \t{\n* \t\t// Make sure the \"onclick\" attribute will pass through.\n* \t\trenderUnsafeAttributes: [ 'onclick' ]\n* \t}\n* );\n* ```\n*\n* @error domconverter-unsafe-attribute-detected\n* @param {HTMLElement} domElement The DOM element the attribute was set on.\n* @param {string} key The original name of the attribute\n* @param {string} value The value of the original attribute\n*/\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/observer\n*/\nconst ObserverBase = /* #__PURE__ */ DomEmitterMixin();\n/**\n* Abstract base observer class. Observers are classes which listen to DOM events, do the preliminary\n* processing and fire events on the {@link module:engine/view/document~ViewDocument} objects.\n* Observers can also add features to the view, for instance by updating its status or marking elements\n* which need a refresh on DOM events.\n*/\nvar Observer = class extends ObserverBase {\n\t/**\n\t* An instance of the view controller.\n\t*/\n\tview;\n\t/**\n\t* A reference to the {@link module:engine/view/document~ViewDocument} object.\n\t*/\n\tdocument;\n\t/**\n\t* The state of the observer. If it is disabled, no events will be fired.\n\t*/\n\t_isEnabled = false;\n\t/**\n\t* Creates an instance of the observer.\n\t*/\n\tconstructor(view) {\n\t\tsuper();\n\t\tthis.view = view;\n\t\tthis.document = view.document;\n\t}\n\t/**\n\t* The state of the observer. If it is disabled, no events will be fired.\n\t*/\n\tget isEnabled() {\n\t\treturn this._isEnabled;\n\t}\n\t/**\n\t* Enables the observer. This method is called when the observer is registered to the\n\t* {@link module:engine/view/view~EditingView} and after {@link module:engine/view/view~EditingView#forceRender rendering}\n\t* (all observers are {@link #disable disabled} before rendering).\n\t*\n\t* A typical use case for disabling observers is that mutation observers need to be disabled for the rendering.\n\t* However, a child class may not need to be disabled, so it can implement an empty method.\n\t*\n\t* @see module:engine/view/observer/observer~Observer#disable\n\t*/\n\tenable() {\n\t\tthis._isEnabled = true;\n\t}\n\t/**\n\t* Disables the observer. This method is called before\n\t* {@link module:engine/view/view~EditingView#forceRender rendering} to prevent firing events during rendering.\n\t*\n\t* @see module:engine/view/observer/observer~Observer#enable\n\t*/\n\tdisable() {\n\t\tthis._isEnabled = false;\n\t}\n\t/**\n\t* Disables and destroys the observer, among others removes event listeners created by the observer.\n\t*/\n\tdestroy() {\n\t\tthis.disable();\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Checks whether a given DOM event should be ignored (should not be turned into a synthetic view document event).\n\t*\n\t* Currently, an event will be ignored only if its target or any of its ancestors has the `data-cke-ignore-events` attribute.\n\t* This attribute can be used inside the structures generated by\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter#createUIElement `ViewDowncastWriter#createUIElement()`} to ignore events\n\t* fired within a UI that should be excluded from CKEditor 5's realms.\n\t*\n\t* @param domTarget The DOM event target to check (usually an element, sometimes a text node and\n\t* potentially sometimes a document, too).\n\t* @returns Whether this event should be ignored by the observer.\n\t*/\n\tcheckShouldIgnoreEventFromTarget(domTarget) {\n\t\tif (domTarget && domTarget.nodeType === 3) domTarget = domTarget.parentNode;\n\t\tif (!domTarget || domTarget.nodeType !== 1) return false;\n\t\treturn domTarget.matches(\"[data-cke-ignore-events], [data-cke-ignore-events] *\");\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/domeventdata\n*/\n/**\n* Information about a DOM event in context of the {@link module:engine/view/document~ViewDocument}.\n* It wraps the native event, which usually should not be used as the wrapper contains\n* additional data (like key code for keyboard events).\n*\n* @typeParam TEvent The type of DOM Event that this class represents.\n*/\nvar ViewDocumentDomEventData = class {\n\t/**\n\t* Instance of the view controller.\n\t*/\n\tview;\n\t/**\n\t* The instance of the document.\n\t*/\n\tdocument;\n\t/**\n\t* The DOM event.\n\t*/\n\tdomEvent;\n\t/**\n\t* The DOM target.\n\t*/\n\tdomTarget;\n\t/**\n\t* @param view The instance of the view controller.\n\t* @param domEvent The DOM event.\n\t* @param additionalData Additional properties that the instance should contain.\n\t*/\n\tconstructor(view, domEvent, additionalData) {\n\t\tthis.view = view;\n\t\tthis.document = view.document;\n\t\tthis.domEvent = domEvent;\n\t\tthis.domTarget = domEvent.target;\n\t\textend(this, additionalData);\n\t}\n\t/**\n\t* The tree view element representing the target.\n\t*/\n\tget target() {\n\t\treturn this.view.domConverter.mapDomToView(this.domTarget);\n\t}\n\t/**\n\t* Prevents the native's event default action.\n\t*/\n\tpreventDefault() {\n\t\tthis.domEvent.preventDefault();\n\t}\n\t/**\n\t* Stops native event propagation.\n\t*/\n\tstopPropagation() {\n\t\tthis.domEvent.stopPropagation();\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/domeventobserver\n*/\n/**\n* Base class for DOM event observers. This class handles\n* {@link module:engine/view/observer/observer~Observer#observe adding} listeners to DOM elements,\n* {@link module:engine/view/observer/observer~Observer#disable disabling} and\n* {@link module:engine/view/observer/observer~Observer#enable re-enabling} events.\n* Child class needs to define\n* {@link module:engine/view/observer/domeventobserver~DomEventObserver#domEventType DOM event type} and\n* {@link module:engine/view/observer/domeventobserver~DomEventObserver#onDomEvent callback}.\n*\n* For instance:\n*\n* ```ts\n* class ClickObserver extends DomEventObserver<'click'> {\n* \t// It can also be defined as a normal property in the constructor.\n* \tget domEventType(): 'click' {\n* \t\treturn 'click';\n* \t}\n*\n* \tonDomEvent( domEvent: MouseEvent ): void {\n* \t\tthis.fire( 'click', domEvent );\n* \t}\n* }\n* ```\n*\n* @typeParam EventType DOM Event type name or an union of those.\n* @typeParam AdditionalData Additional data passed along with the event.\n*/\nvar DomEventObserver = class extends Observer {\n\t/**\n\t* If set to `true` DOM events will be listened on the capturing phase.\n\t* Default value is `false`.\n\t*/\n\tuseCapture = false;\n\t/**\n\t* If set to `true`, indicates that the function specified by listener will never call `preventDefault()`.\n\t* Default value is `false`.\n\t*/\n\tusePassive = false;\n\t/**\n\t* @inheritDoc\n\t*/\n\tobserve(domElement) {\n\t\t(typeof this.domEventType == \"string\" ? [this.domEventType] : this.domEventType).forEach((type) => {\n\t\t\tthis.listenTo(domElement, type, (eventInfo, domEvent) => {\n\t\t\t\tif (this.isEnabled && !this.checkShouldIgnoreEventFromTarget(domEvent.target)) this.onDomEvent(domEvent);\n\t\t\t}, {\n\t\t\t\tuseCapture: this.useCapture,\n\t\t\t\tusePassive: this.usePassive\n\t\t\t});\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstopObserving(domElement) {\n\t\tthis.stopListening(domElement);\n\t}\n\t/**\n\t* Calls `Document#fire()` if observer {@link #isEnabled is enabled}.\n\t*\n\t* @see module:utils/emittermixin~Emitter#fire\n\t* @param eventType The event type (name).\n\t* @param domEvent The DOM event.\n\t* @param additionalData The additional data which should extend the\n\t* {@link module:engine/view/observer/domeventdata~ViewDocumentDomEventData event data} object.\n\t*/\n\tfire(eventType, domEvent, additionalData) {\n\t\tif (this.isEnabled) this.document.fire(eventType, new ViewDocumentDomEventData(this.view, domEvent, additionalData));\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/keyobserver\n*/\n/**\n* Observer for events connected with pressing keyboard keys.\n*\n* Note that this observer is attached by the {@link module:engine/view/view~EditingView} and is available by default.\n*/\nvar KeyObserver = class extends DomEventObserver {\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = [\"keydown\", \"keyup\"];\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvt) {\n\t\tconst data = {\n\t\t\tkeyCode: domEvt.keyCode,\n\t\t\taltKey: domEvt.altKey,\n\t\t\tctrlKey: domEvt.ctrlKey,\n\t\t\tshiftKey: domEvt.shiftKey,\n\t\t\tmetaKey: domEvt.metaKey,\n\t\t\tget keystroke() {\n\t\t\t\treturn getCode(this);\n\t\t\t}\n\t\t};\n\t\tthis.fire(domEvt.type, domEvt, data);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/fakeselectionobserver\n*/\n/**\n* Fake selection observer class. If view selection is fake it is placed in dummy DOM container. This observer listens\n* on {@link module:engine/view/document~ViewDocument#event:keydown keydown} events and handles moving\n* fake view selection to the correct place if arrow keys are pressed.\n* Fires {@link module:engine/view/document~ViewDocument#event:selectionChange selectionChange event} simulating natural behaviour of\n* {@link module:engine/view/observer/selectionobserver~SelectionObserver SelectionObserver}.\n*/\nvar FakeSelectionObserver = class extends Observer {\n\t/**\n\t* Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.\n\t*/\n\t_fireSelectionChangeDoneDebounced;\n\t/**\n\t* Creates new FakeSelectionObserver instance.\n\t*/\n\tconstructor(view) {\n\t\tsuper(view);\n\t\tthis._fireSelectionChangeDoneDebounced = debounce((data) => {\n\t\t\tthis.document.fire(\"selectionChangeDone\", data);\n\t\t}, 200);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tobserve() {\n\t\tconst document = this.document;\n\t\tdocument.on(\"arrowKey\", (eventInfo, data) => {\n\t\t\tif (document.selection.isFake && this.isEnabled) data.preventDefault();\n\t\t}, { context: \"$capture\" });\n\t\tdocument.on(\"arrowKey\", (eventInfo, data) => {\n\t\t\tif (document.selection.isFake && this.isEnabled) this._handleSelectionMove(data.keyCode);\n\t\t}, { priority: \"lowest\" });\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstopObserving() {}\n\t/**\n\t* @inheritDoc\n\t*/\n\tdestroy() {\n\t\tsuper.destroy();\n\t\tthis._fireSelectionChangeDoneDebounced.cancel();\n\t}\n\t/**\n\t* Handles collapsing view selection according to given key code. If left or up key is provided - new selection will be\n\t* collapsed to left. If right or down key is pressed - new selection will be collapsed to right.\n\t*\n\t* This method fires {@link module:engine/view/document~ViewDocument#event:selectionChange} and\n\t* {@link module:engine/view/document~ViewDocument#event:selectionChangeDone} events imitating behaviour of\n\t* {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n\t*/\n\t_handleSelectionMove(keyCode) {\n\t\tconst selection = this.document.selection;\n\t\tconst newSelection = new ViewSelection(selection.getRanges(), {\n\t\t\tbackward: selection.isBackward,\n\t\t\tfake: false\n\t\t});\n\t\tif (keyCode == keyCodes.arrowleft || keyCode == keyCodes.arrowup) newSelection.setTo(newSelection.getFirstPosition());\n\t\tif (keyCode == keyCodes.arrowright || keyCode == keyCodes.arrowdown) newSelection.setTo(newSelection.getLastPosition());\n\t\tconst data = {\n\t\t\toldSelection: selection,\n\t\t\tnewSelection,\n\t\t\tdomSelection: null\n\t\t};\n\t\tthis.document.fire(\"selectionChange\", data);\n\t\tthis._fireSelectionChangeDoneDebounced(data);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/mutationobserver\n*/\n/**\n* Mutation observer's role is to watch for any DOM changes inside the editor that weren't\n* done by the editor's {@link module:engine/view/renderer~ViewRenderer} itself and reverting these changes.\n*\n* It does this by observing all mutations in the DOM, marking related view elements as changed and calling\n* {@link module:engine/view/renderer~ViewRenderer#render}. Because all mutated nodes are marked as\n* \"to be rendered\" and the {@link module:engine/view/renderer~ViewRenderer#render `render()`} method is called,\n* all changes are reverted in the DOM (the DOM is synced with the editor's view structure).\n*\n* Note that this observer is attached by the {@link module:engine/view/view~EditingView} and is available by default.\n*/\nvar MutationObserver = class extends Observer {\n\t/**\n\t* Reference to the {@link module:engine/view/view~EditingView#domConverter}.\n\t*/\n\tdomConverter;\n\t/**\n\t* Native mutation observer config.\n\t*/\n\t_config;\n\t/**\n\t* Observed DOM elements.\n\t*/\n\t_domElements;\n\t/**\n\t* Native mutation observer.\n\t*/\n\t_mutationObserver;\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(view) {\n\t\tsuper(view);\n\t\tthis._config = {\n\t\t\tchildList: true,\n\t\t\tcharacterData: true,\n\t\t\tsubtree: true\n\t\t};\n\t\tthis.domConverter = view.domConverter;\n\t\tthis._domElements = /* @__PURE__ */ new Set();\n\t\tthis._mutationObserver = new window.MutationObserver(this._onMutations.bind(this));\n\t}\n\t/**\n\t* Synchronously handles mutations and empties the queue.\n\t*/\n\tflush() {\n\t\tthis._onMutations(this._mutationObserver.takeRecords());\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tobserve(domElement) {\n\t\tthis._domElements.add(domElement);\n\t\tif (this.isEnabled) this._mutationObserver.observe(domElement, this._config);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstopObserving(domElement) {\n\t\tthis._domElements.delete(domElement);\n\t\tif (this.isEnabled) {\n\t\t\tthis._mutationObserver.disconnect();\n\t\t\tfor (const domElement of this._domElements) this._mutationObserver.observe(domElement, this._config);\n\t\t}\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tenable() {\n\t\tsuper.enable();\n\t\tfor (const domElement of this._domElements) this._mutationObserver.observe(domElement, this._config);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tdisable() {\n\t\tsuper.disable();\n\t\tthis._mutationObserver.disconnect();\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tdestroy() {\n\t\tsuper.destroy();\n\t\tthis._mutationObserver.disconnect();\n\t}\n\t/**\n\t* Handles mutations. Mark view elements to sync and call render.\n\t*\n\t* @param domMutations Array of native mutations.\n\t*/\n\t_onMutations(domMutations) {\n\t\tif (domMutations.length === 0) return;\n\t\tconst domConverter = this.domConverter;\n\t\tconst mutatedTextNodes = /* @__PURE__ */ new Set();\n\t\tconst elementsWithMutatedChildren = /* @__PURE__ */ new Set();\n\t\tfor (const mutation of domMutations) {\n\t\t\tconst element = domConverter.mapDomToView(mutation.target);\n\t\t\tif (!element) continue;\n\t\t\tif (element.is(\"uiElement\") || element.is(\"rawElement\")) continue;\n\t\t\tif (mutation.type === \"childList\" && !this._isBogusBrMutation(mutation)) elementsWithMutatedChildren.add(element);\n\t\t}\n\t\tfor (const mutation of domMutations) {\n\t\t\tconst element = domConverter.mapDomToView(mutation.target);\n\t\t\tif (element && (element.is(\"uiElement\") || element.is(\"rawElement\"))) continue;\n\t\t\tif (mutation.type === \"characterData\") {\n\t\t\t\tconst text = domConverter.findCorrespondingViewText(mutation.target);\n\t\t\t\tif (text && !elementsWithMutatedChildren.has(text.parent)) mutatedTextNodes.add(text);\n\t\t\t\telse if (!text && startsWithFiller(mutation.target)) elementsWithMutatedChildren.add(domConverter.mapDomToView(mutation.target.parentNode));\n\t\t\t}\n\t\t}\n\t\tconst mutations = [];\n\t\tfor (const textNode of mutatedTextNodes) mutations.push({\n\t\t\ttype: \"text\",\n\t\t\tnode: textNode\n\t\t});\n\t\tfor (const viewElement of elementsWithMutatedChildren) {\n\t\t\tconst domElement = domConverter.mapViewToDom(viewElement);\n\t\t\tconst viewChildren = Array.from(viewElement.getChildren());\n\t\t\tconst newViewChildren = Array.from(domConverter.domChildrenToView(domElement, { withChildren: false }));\n\t\t\tif (!isEqualWith(viewChildren, newViewChildren, sameNodes)) mutations.push({\n\t\t\t\ttype: \"children\",\n\t\t\t\tnode: viewElement\n\t\t\t});\n\t\t}\n\t\tif (mutations.length) this.document.fire(\"mutations\", { mutations });\n\t}\n\t/**\n\t* Checks if mutation was generated by the browser inserting bogus br on the end of the block element.\n\t* Such mutations are generated while pressing space or performing native spellchecker correction\n\t* on the end of the block element in Firefox browser.\n\t*\n\t* @param mutation Native mutation object.\n\t*/\n\t_isBogusBrMutation(mutation) {\n\t\tlet addedNode = null;\n\t\tif (mutation.nextSibling === null && mutation.removedNodes.length === 0 && mutation.addedNodes.length == 1) addedNode = this.domConverter.domToView(mutation.addedNodes[0], { withChildren: false });\n\t\treturn addedNode && addedNode.is(\"element\", \"br\");\n\t}\n};\nfunction sameNodes(child1, child2) {\n\tif (Array.isArray(child1)) return;\n\tif (child1 === child2) return true;\n\telse if (child1.is(\"$text\") && child2.is(\"$text\")) return child1.data === child2.data;\n\treturn false;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/focusobserver\n*/\n/**\n* {@link module:engine/view/document~ViewDocument#event:focus Focus}\n* and {@link module:engine/view/document~ViewDocument#event:blur blur} events observer.\n* Focus observer handle also {@link module:engine/view/rooteditableelement~ViewRootEditableElement#isFocused isFocused} property of the\n* {@link module:engine/view/rooteditableelement~ViewRootEditableElement root elements}.\n*\n* Note that this observer is attached by the {@link module:engine/view/view~EditingView} and is available by default.\n*/\nvar FocusObserver = class extends DomEventObserver {\n\t/**\n\t* Identifier of the timeout currently used by focus listener to delay rendering execution.\n\t*/\n\t_renderTimeoutId = null;\n\t/**\n\t* Set to `true` if the document is in the process of setting the focus.\n\t*\n\t* The flag is used to indicate that setting the focus is in progress.\n\t*/\n\t_isFocusChanging = false;\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = [\"focus\", \"blur\"];\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(view) {\n\t\tsuper(view);\n\t\tthis.useCapture = true;\n\t\tconst document = this.document;\n\t\tdocument.on(\"focus\", () => this._handleFocus());\n\t\tdocument.on(\"blur\", (evt, data) => this._handleBlur(data));\n\t\tdocument.on(\"beforeinput\", () => {\n\t\t\tif (!document.isFocused) this._handleFocus();\n\t\t}, { priority: \"highest\" });\n\t}\n\t/**\n\t* Finishes setting the document focus state.\n\t*/\n\tflush() {\n\t\tif (this._isFocusChanging) {\n\t\t\tthis._isFocusChanging = false;\n\t\t\tthis.document.isFocused = true;\n\t\t}\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvent) {\n\t\tthis.fire(domEvent.type, domEvent);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tdestroy() {\n\t\tthis._clearTimeout();\n\t\tsuper.destroy();\n\t}\n\t/**\n\t* The `focus` event handler.\n\t*/\n\t_handleFocus() {\n\t\tthis._clearTimeout();\n\t\tthis._isFocusChanging = true;\n\t\tthis._renderTimeoutId = setTimeout(() => {\n\t\t\tthis._renderTimeoutId = null;\n\t\t\tthis.flush();\n\t\t\tthis.view.change(() => {});\n\t\t}, 50);\n\t}\n\t/**\n\t* The `blur` event handler.\n\t*/\n\t_handleBlur(data) {\n\t\tconst selectedEditable = this.document.selection.editableElement;\n\t\tif (selectedEditable === null || selectedEditable === data.target) {\n\t\t\tthis.document.isFocused = false;\n\t\t\tthis._isFocusChanging = false;\n\t\t\tthis.view.change(() => {});\n\t\t}\n\t}\n\t/**\n\t* Clears timeout.\n\t*/\n\t_clearTimeout() {\n\t\tif (this._renderTimeoutId) {\n\t\t\tclearTimeout(this._renderTimeoutId);\n\t\t\tthis._renderTimeoutId = null;\n\t\t}\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/selectionobserver\n*/\n/**\n* Selection observer class observes selection changes in the document. If a selection changes on the document this\n* observer checks if the DOM selection is different from the {@link module:engine/view/document~ViewDocument#selection view selection}.\n* The selection observer fires {@link module:engine/view/document~ViewDocument#event:selectionChange} event only if\n* a selection change was the only change in the document and the DOM selection is different from the view selection.\n*\n* This observer also manages the {@link module:engine/view/document~ViewDocument#isSelecting} property of the view document.\n*\n* Note that this observer is attached by the {@link module:engine/view/view~EditingView} and is available by default.\n*/\nvar SelectionObserver = class extends Observer {\n\t/**\n\t* Instance of the mutation observer. Selection observer calls\n\t* {@link module:engine/view/observer/mutationobserver~MutationObserver#flush} to ensure that the mutations will be handled\n\t* before the {@link module:engine/view/document~ViewDocument#event:selectionChange} event is fired.\n\t*/\n\tmutationObserver;\n\t/**\n\t* Instance of the focus observer. Focus observer calls\n\t* {@link module:engine/view/observer/focusobserver~FocusObserver#flush} to mark the latest focus change as complete.\n\t*/\n\tfocusObserver;\n\t/**\n\t* Reference to the view {@link module:engine/view/documentselection~ViewDocumentSelection} object used to compare\n\t* new selection with it.\n\t*/\n\tselection;\n\t/**\n\t* Reference to the {@link module:engine/view/view~EditingView#domConverter}.\n\t*/\n\tdomConverter;\n\t/**\n\t* A set of documents which have added `selectionchange` listener to avoid adding a listener twice to the same\n\t* document.\n\t*/\n\t_documents = /* @__PURE__ */ new WeakSet();\n\t/**\n\t* Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.\n\t*/\n\t_fireSelectionChangeDoneDebounced;\n\t/**\n\t* When called, starts clearing the {@link #_loopbackCounter} counter in time intervals. When the number of selection\n\t* changes exceeds a certain limit within the interval of time, the observer will not fire `selectionChange` but warn about\n\t* possible infinite selection loop.\n\t*/\n\t_clearInfiniteLoopInterval;\n\t/**\n\t* Unlocks the `isSelecting` state of the view document in case the selection observer did not record this fact\n\t* correctly (for whatever reason). It is a safeguard (paranoid check), that returns document to the normal state\n\t* after a certain period of time (debounced, postponed by each selectionchange event).\n\t*/\n\t_documentIsSelectingInactivityTimeoutDebounced;\n\t/**\n\t* Private property to check if the code does not enter infinite loop.\n\t*/\n\t_loopbackCounter = 0;\n\t/**\n\t* A set of DOM documents that have a pending selection change.\n\t* Pending selection change is recorded while selection change event is detected on non focused editable.\n\t*/\n\t_pendingSelectionChange = /* @__PURE__ */ new Set();\n\tconstructor(view) {\n\t\tsuper(view);\n\t\tthis.mutationObserver = view.getObserver(MutationObserver);\n\t\tthis.focusObserver = view.getObserver(FocusObserver);\n\t\tthis.selection = this.document.selection;\n\t\tthis.domConverter = view.domConverter;\n\t\tthis._fireSelectionChangeDoneDebounced = debounce((data) => {\n\t\t\tthis.document.fire(\"selectionChangeDone\", data);\n\t\t}, 200);\n\t\tthis._clearInfiniteLoopInterval = setInterval(() => this._clearInfiniteLoop(), 1e3);\n\t\tthis._documentIsSelectingInactivityTimeoutDebounced = debounce(() => this.document.isSelecting = false, 5e3);\n\t\tthis.view.document.on(\"change:isFocused\", (evt, name, isFocused) => {\n\t\t\tif (isFocused && this._pendingSelectionChange.size) {\n\t\t\t\tfor (const domDocument of Array.from(this._pendingSelectionChange)) this._handleSelectionChange(domDocument);\n\t\t\t\tthis._pendingSelectionChange.clear();\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tobserve(domElement) {\n\t\tconst domDocument = domElement.ownerDocument;\n\t\tconst startDocumentIsSelecting = () => {\n\t\t\tthis.document.isSelecting = true;\n\t\t\tthis._documentIsSelectingInactivityTimeoutDebounced();\n\t\t};\n\t\tconst endDocumentIsSelecting = () => {\n\t\t\tif (!this.document.isSelecting) return;\n\t\t\tthis._handleSelectionChange(domDocument);\n\t\t\tthis.document.isSelecting = false;\n\t\t\tthis._documentIsSelectingInactivityTimeoutDebounced.cancel();\n\t\t};\n\t\tthis.listenTo(domElement, \"selectstart\", startDocumentIsSelecting, { priority: \"highest\" });\n\t\tthis.listenTo(domElement, \"keydown\", endDocumentIsSelecting, {\n\t\t\tpriority: \"highest\",\n\t\t\tuseCapture: true\n\t\t});\n\t\tthis.listenTo(domElement, \"keyup\", endDocumentIsSelecting, {\n\t\t\tpriority: \"highest\",\n\t\t\tuseCapture: true\n\t\t});\n\t\tif (this._documents.has(domDocument)) return;\n\t\tthis.listenTo(domDocument, \"mouseup\", endDocumentIsSelecting, {\n\t\t\tpriority: \"highest\",\n\t\t\tuseCapture: true\n\t\t});\n\t\tthis.listenTo(domDocument, \"selectionchange\", () => {\n\t\t\tif (this.document.isComposing && !env.isAndroid) return;\n\t\t\tthis._handleSelectionChange(domDocument);\n\t\t\tthis._documentIsSelectingInactivityTimeoutDebounced();\n\t\t});\n\t\tthis.listenTo(this.view.document, \"compositionstart\", () => {\n\t\t\tthis._handleSelectionChange(domDocument);\n\t\t}, { priority: \"lowest\" });\n\t\tthis._documents.add(domDocument);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstopObserving(domElement) {\n\t\tthis.stopListening(domElement);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tdestroy() {\n\t\tsuper.destroy();\n\t\tclearInterval(this._clearInfiniteLoopInterval);\n\t\tthis._fireSelectionChangeDoneDebounced.cancel();\n\t\tthis._documentIsSelectingInactivityTimeoutDebounced.cancel();\n\t}\n\t/* v8 ignore next 6 -- @preserve */\n\t_reportInfiniteLoop() {}\n\t/**\n\t* Selection change listener. {@link module:engine/view/observer/mutationobserver~MutationObserver#flush Flush} mutations, check if\n\t* a selection changes and fires {@link module:engine/view/document~ViewDocument#event:selectionChange} event on every change\n\t* and {@link module:engine/view/document~ViewDocument#event:selectionChangeDone} when a selection stop changing.\n\t*\n\t* @param domDocument DOM document.\n\t*/\n\t_handleSelectionChange(domDocument) {\n\t\tif (!this.isEnabled) return;\n\t\tconst domSelection = domDocument.defaultView.getSelection();\n\t\tif (this.checkShouldIgnoreEventFromTarget(domSelection.anchorNode)) return;\n\t\tthis.mutationObserver.flush();\n\t\tconst newViewSelection = this.domConverter.domSelectionToView(domSelection);\n\t\tif (newViewSelection.rangeCount == 0) {\n\t\t\tthis.view.hasDomSelection = false;\n\t\t\treturn;\n\t\t}\n\t\tthis.view.hasDomSelection = true;\n\t\tthis.focusObserver.flush();\n\t\tif (!this.view.document.isFocused && !this.view.document.isReadOnly) {\n\t\t\tthis._pendingSelectionChange.add(domDocument);\n\t\t\treturn;\n\t\t}\n\t\tthis._pendingSelectionChange.delete(domDocument);\n\t\tif (this.selection.isEqual(newViewSelection) && this.domConverter.isDomSelectionCorrect(domSelection)) return;\n\t\tif (++this._loopbackCounter > 60) {\n\t\t\tthis._reportInfiniteLoop();\n\t\t\treturn;\n\t\t}\n\t\tif (!isSelectionWithinRootElements(newViewSelection)) this.view.forceRender();\n\t\telse if (this.selection.isSimilar(newViewSelection)) this.view.forceRender();\n\t\telse {\n\t\t\tconst data = {\n\t\t\t\toldSelection: this.selection,\n\t\t\t\tnewSelection: newViewSelection,\n\t\t\t\tdomSelection\n\t\t\t};\n\t\t\tthis.document.fire(\"selectionChange\", data);\n\t\t\tthis._fireSelectionChangeDoneDebounced(data);\n\t\t}\n\t}\n\t/**\n\t* Clears `SelectionObserver` internal properties connected with preventing infinite loop.\n\t*/\n\t_clearInfiniteLoop() {\n\t\tthis._loopbackCounter = 0;\n\t}\n};\n/**\n* Checks if all roots of the selection's range boundaries are root elements.\n* Returns true if the selection is fully contained within root elements (not orphaned).\n*\n* @param selection The view selection to check.\n* @returns True if all range boundaries are within root elements, false otherwise.\n*/\nfunction isSelectionWithinRootElements(selection) {\n\treturn Array.from(selection.getRanges()).flatMap((range) => [range.start.root, range.end.root]).every((root) => root && root.is(\"rootElement\"));\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/compositionobserver\n*/\n/**\n* {@link module:engine/view/document~ViewDocument#event:compositionstart Compositionstart},\n* {@link module:engine/view/document~ViewDocument#event:compositionupdate compositionupdate} and\n* {@link module:engine/view/document~ViewDocument#event:compositionend compositionend} events observer.\n*\n* Note that this observer is attached by the {@link module:engine/view/view~EditingView} and is available by default.\n*/\nvar CompositionObserver = class extends DomEventObserver {\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = [\n\t\t\"compositionstart\",\n\t\t\"compositionupdate\",\n\t\t\"compositionend\"\n\t];\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(view) {\n\t\tsuper(view);\n\t\tconst document = this.document;\n\t\tdocument.on(\"compositionstart\", () => {\n\t\t\tdocument.isComposing = true;\n\t\t});\n\t\tdocument.on(\"compositionend\", () => {\n\t\t\tdocument.isComposing = false;\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvent) {\n\t\tthis.fire(domEvent.type, domEvent, { data: domEvent.data });\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* A facade over the native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.\n*/\nvar ViewDataTransfer = class {\n\t/**\n\t* The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.\n\t*/\n\t_files;\n\t/**\n\t* The native DataTransfer object.\n\t*/\n\t_native;\n\t/**\n\t* @param nativeDataTransfer The native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.\n\t* @param options.cacheFiles Whether `files` list should be initialized in the constructor.\n\t*/\n\tconstructor(nativeDataTransfer, options = {}) {\n\t\tthis._files = options.cacheFiles ? getFiles(nativeDataTransfer) : null;\n\t\tthis._native = nativeDataTransfer;\n\t}\n\t/**\n\t* The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.\n\t*/\n\tget files() {\n\t\tif (!this._files) this._files = getFiles(this._native);\n\t\treturn this._files;\n\t}\n\t/**\n\t* Returns an array of available native content types.\n\t*/\n\tget types() {\n\t\treturn this._native.types;\n\t}\n\t/**\n\t* Gets the data from the data transfer by its MIME type.\n\t*\n\t* ```ts\n\t* dataTransfer.getData( 'text/plain' );\n\t* ```\n\t*\n\t* @param type The MIME type. E.g. `text/html` or `text/plain`.\n\t*/\n\tgetData(type) {\n\t\treturn this._native.getData(type);\n\t}\n\t/**\n\t* Sets the data in the data transfer.\n\t*\n\t* @param type The MIME type. E.g. `text/html` or `text/plain`.\n\t*/\n\tsetData(type, data) {\n\t\tthis._native.setData(type, data);\n\t}\n\t/**\n\t* The effect that is allowed for a drag operation.\n\t*/\n\tset effectAllowed(value) {\n\t\tthis._native.effectAllowed = value;\n\t}\n\tget effectAllowed() {\n\t\treturn this._native.effectAllowed;\n\t}\n\t/**\n\t* The actual drop effect.\n\t*/\n\tset dropEffect(value) {\n\t\tthis._native.dropEffect = value;\n\t}\n\tget dropEffect() {\n\t\treturn this._native.dropEffect;\n\t}\n\t/**\n\t* Set a preview image of the dragged content.\n\t*/\n\tsetDragImage(image, x, y) {\n\t\tthis._native.setDragImage(image, x, y);\n\t}\n\t/**\n\t* Whether the dragging operation was canceled.\n\t*/\n\tget isCanceled() {\n\t\treturn this._native.dropEffect == \"none\" || !!this._native.mozUserCancelled;\n\t}\n};\nfunction getFiles(nativeDataTransfer) {\n\tconst files = Array.from(nativeDataTransfer.files || []);\n\tconst items = Array.from(nativeDataTransfer.items || []);\n\tif (files.length) return files;\n\treturn items.filter((item) => item.kind === \"file\").map((item) => item.getAsFile());\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/inputobserver\n*/\n/**\n* Observer for events connected with data input.\n*\n* **Note**: This observer is attached by {@link module:engine/view/view~EditingView} and available by default in all\n* editor instances.\n*/\nvar InputObserver = class extends DomEventObserver {\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = \"beforeinput\";\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvent) {\n\t\tconst domTargetRanges = domEvent.getTargetRanges();\n\t\tconst view = this.view;\n\t\tconst viewDocument = view.document;\n\t\tlet dataTransfer = null;\n\t\tlet data = null;\n\t\tlet targetRanges = [];\n\t\tif (domEvent.dataTransfer) dataTransfer = new ViewDataTransfer(domEvent.dataTransfer);\n\t\tif (domEvent.data !== null) data = domEvent.data;\n\t\telse if (dataTransfer) data = dataTransfer.getData(\"text/plain\");\n\t\tif (viewDocument.selection.isFake) {\n\t\t\ttargetRanges = Array.from(viewDocument.selection.getRanges());\n\t\t\tdomEvent.preventDefault();\n\t\t} else if (domTargetRanges.length) targetRanges = domTargetRanges.map((domRange) => {\n\t\t\tlet viewStart = view.domConverter.domPositionToView(domRange.startContainer, domRange.startOffset);\n\t\t\tconst viewEnd = view.domConverter.domPositionToView(domRange.endContainer, domRange.endOffset);\n\t\t\tif (viewStart && startsWithFiller(domRange.startContainer) && domRange.startOffset < 7) {\n\t\t\t\tdomEvent.preventDefault();\n\t\t\t\tlet count = 7 - domRange.startOffset;\n\t\t\t\tviewStart = viewStart.getLastMatchingPosition((value) => {\n\t\t\t\t\tif (value.item.is(\"attributeElement\") || value.item.is(\"uiElement\")) return true;\n\t\t\t\t\tif (value.item.is(\"$textProxy\") && count--) return true;\n\t\t\t\t\treturn false;\n\t\t\t\t}, {\n\t\t\t\t\tdirection: \"backward\",\n\t\t\t\t\tsingleCharacters: true\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (isFollowedByInlineFiller(domRange.endContainer, domRange.endOffset)) domEvent.preventDefault();\n\t\t\tif (viewStart) return view.createRange(viewStart, viewEnd);\n\t\t\telse if (viewEnd) return view.createRange(viewEnd);\n\t\t}).filter((range) => !!range);\n\t\telse if (env.isAndroid) {\n\t\t\tconst domSelection = domEvent.target.ownerDocument.defaultView.getSelection();\n\t\t\ttargetRanges = Array.from(view.domConverter.domSelectionToView(domSelection).getRanges());\n\t\t}\n\t\tif (env.isAndroid && domEvent.inputType == \"insertCompositionText\" && data && data.endsWith(\"\\n\")) {\n\t\t\tthis.fire(domEvent.type, domEvent, {\n\t\t\t\tinputType: \"insertParagraph\",\n\t\t\t\ttargetRanges: [view.createRange(targetRanges[0].end)]\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif ([\"insertText\", \"insertReplacementText\"].includes(domEvent.inputType) && data && data.includes(\"\\n\")) {\n\t\t\tconst parts = data.split(/\\n{1,2}/g);\n\t\t\tlet partTargetRanges = targetRanges;\n\t\t\tdomEvent.preventDefault();\n\t\t\tfor (let i = 0; i < parts.length; i++) {\n\t\t\t\tconst dataPart = parts[i];\n\t\t\t\tif (dataPart != \"\") {\n\t\t\t\t\tthis.fire(domEvent.type, domEvent, {\n\t\t\t\t\t\tdata: dataPart,\n\t\t\t\t\t\tdataTransfer,\n\t\t\t\t\t\ttargetRanges: partTargetRanges,\n\t\t\t\t\t\tinputType: domEvent.inputType,\n\t\t\t\t\t\tisComposing: domEvent.isComposing\n\t\t\t\t\t});\n\t\t\t\t\tpartTargetRanges = [viewDocument.selection.getFirstRange()];\n\t\t\t\t}\n\t\t\t\tif (i + 1 < parts.length) {\n\t\t\t\t\tthis.fire(domEvent.type, domEvent, {\n\t\t\t\t\t\tinputType: \"insertParagraph\",\n\t\t\t\t\t\ttargetRanges: partTargetRanges\n\t\t\t\t\t});\n\t\t\t\t\tpartTargetRanges = [viewDocument.selection.getFirstRange()];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis.fire(domEvent.type, domEvent, {\n\t\t\tdata,\n\t\t\tdataTransfer,\n\t\t\ttargetRanges,\n\t\t\tinputType: domEvent.inputType,\n\t\t\tisComposing: domEvent.isComposing\n\t\t});\n\t}\n};\n/**\n* Returns `true` if there is an inline filler just after the position in DOM.\n* It walks up the DOM tree if the offset is at the end of the node.\n*/\nfunction isFollowedByInlineFiller(node, offset) {\n\twhile (node.parentNode) {\n\t\tif (isText(node)) {\n\t\t\tif (offset != node.data.length) return false;\n\t\t} else if (offset != node.childNodes.length) return false;\n\t\toffset = indexOf(node) + 1;\n\t\tnode = node.parentNode;\n\t\tif (offset < node.childNodes.length && startsWithFiller(node.childNodes[offset])) return true;\n\t}\n\treturn false;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/arrowkeysobserver\n*/\n/**\n* Arrow keys observer introduces the {@link module:engine/view/document~ViewDocument#event:arrowKey `Document#arrowKey`} event.\n*\n* Note that this observer is attached by the {@link module:engine/view/view~EditingView} and is available by default.\n*/\nvar ArrowKeysObserver = class extends Observer {\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(view) {\n\t\tsuper(view);\n\t\tthis.document.on(\"keydown\", (event, data) => {\n\t\t\tif (this.isEnabled && isArrowKeyCode(data.keyCode)) {\n\t\t\t\tconst eventInfo = new BubblingEventInfo(this.document, \"arrowKey\", this.document.selection.getFirstRange());\n\t\t\t\tthis.document.fire(eventInfo, data);\n\t\t\t\tif (eventInfo.stop.called) event.stop();\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tobserve() {}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstopObserving() {}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Tab observer introduces the {@link module:engine/view/document~ViewDocument#event:tab `Document#tab`} event.\n*\n* Note that because {@link module:engine/view/observer/tabobserver~TabObserver} is attached by the\n* {@link module:engine/view/view~EditingView}, this event is available by default.\n*/\nvar TabObserver = class extends Observer {\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(view) {\n\t\tsuper(view);\n\t\tconst doc = this.document;\n\t\tdoc.on(\"keydown\", (evt, data) => {\n\t\t\tif (!this.isEnabled || data.keyCode != keyCodes.tab || data.ctrlKey) return;\n\t\t\tconst event = new BubblingEventInfo(doc, \"tab\", doc.selection.getFirstRange());\n\t\t\tdoc.fire(event, data);\n\t\t\tif (event.stop.called) evt.stop();\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tobserve() {}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstopObserving() {}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/view\n*/\nconst EditingViewBase = /* #__PURE__ */ ObservableMixin();\n/**\n* Editor's view controller class. Its main responsibility is DOM - View management for editing purposes, to provide\n* abstraction over the DOM structure and events and hide all browsers quirks.\n*\n* View controller renders view document to DOM whenever view structure changes. To determine when view can be rendered,\n* all changes need to be done using the {@link module:engine/view/view~EditingView#change} method, using\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter}:\n*\n* ```ts\n* view.change( writer => {\n* \twriter.insert( position, writer.createText( 'foo' ) );\n* } );\n* ```\n*\n* View controller also register {@link module:engine/view/observer/observer~Observer observers} which observes changes\n* on DOM and fire events on the {@link module:engine/view/document~ViewDocument Document}.\n* Note that the following observers are added by the class constructor and are always available:\n*\n* * {@link module:engine/view/observer/selectionobserver~SelectionObserver},\n* * {@link module:engine/view/observer/focusobserver~FocusObserver},\n* * {@link module:engine/view/observer/keyobserver~KeyObserver},\n* * {@link module:engine/view/observer/fakeselectionobserver~FakeSelectionObserver}.\n* * {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n* * {@link module:engine/view/observer/inputobserver~InputObserver}.\n* * {@link module:engine/view/observer/arrowkeysobserver~ArrowKeysObserver}.\n* * {@link module:engine/view/observer/tabobserver~TabObserver}.\n*\n* This class also {@link module:engine/view/view~EditingView#attachDomRoot binds the DOM and the view elements}.\n*\n* If you do not need full a DOM - view management, and only want to transform a tree of view elements to a tree of DOM\n* elements you do not need this controller. You can use the {@link module:engine/view/domconverter~ViewDomConverter ViewDomConverter}\n* instead.\n*/\nvar EditingView = class extends EditingViewBase {\n\t/**\n\t* Instance of the {@link module:engine/view/document~ViewDocument} associated with this view controller.\n\t*/\n\tdocument;\n\t/**\n\t* Instance of the {@link module:engine/view/domconverter~ViewDomConverter domConverter} used by\n\t* {@link module:engine/view/view~EditingView#_renderer renderer}\n\t* and {@link module:engine/view/observer/observer~Observer observers}.\n\t*/\n\tdomConverter;\n\t/**\n\t* Roots of the DOM tree. Map on the `HTMLElement`s with roots names as keys.\n\t*/\n\tdomRoots = /* @__PURE__ */ new Map();\n\t/**\n\t* Instance of the {@link module:engine/view/renderer~ViewRenderer renderer}.\n\t*/\n\t_renderer;\n\t/**\n\t* A DOM root attributes cache. It saves the initial values of DOM root attributes before the DOM element\n\t* is {@link module:engine/view/view~EditingView#attachDomRoot attached} to the view so later on, when\n\t* the view is destroyed ({@link module:engine/view/view~EditingView#detachDomRoot}), they can be easily restored.\n\t* This way, the DOM element can go back to the (clean) state as if the editing view never used it.\n\t*/\n\t_initialDomRootAttributes = /* @__PURE__ */ new WeakMap();\n\t/**\n\t* Map of registered {@link module:engine/view/observer/observer~Observer observers}.\n\t*/\n\t_observers = /* @__PURE__ */ new Map();\n\t/**\n\t* ViewDowncastWriter instance used in {@link #change change method} callbacks.\n\t*/\n\t_writer;\n\t/**\n\t* Is set to `true` when {@link #change view changes} are currently in progress.\n\t*/\n\t_ongoingChange = false;\n\t/**\n\t* Used to prevent calling {@link #forceRender} and {@link #change} during rendering view to the DOM.\n\t*/\n\t_postFixersInProgress = false;\n\t/**\n\t* Internal flag to temporary disable rendering. See the usage in the {@link #_disableRendering}.\n\t*/\n\t_renderingDisabled = false;\n\t/**\n\t* Internal flag that disables rendering when there are no changes since the last rendering.\n\t* It stores information about changed selection and changed elements from attached document roots.\n\t*/\n\t_hasChangedSinceTheLastRendering = false;\n\t/**\n\t* @param stylesProcessor The styles processor instance.\n\t*/\n\tconstructor(stylesProcessor) {\n\t\tsuper();\n\t\tthis.document = new ViewDocument(stylesProcessor);\n\t\tthis.domConverter = new ViewDomConverter(this.document);\n\t\tthis.set(\"isRenderingInProgress\", false);\n\t\tthis.set(\"hasDomSelection\", false);\n\t\tthis._renderer = new ViewRenderer(this.domConverter, this.document.selection);\n\t\tthis._renderer.bind(\"isFocused\", \"isSelecting\", \"isComposing\").to(this.document, \"isFocused\", \"isSelecting\", \"isComposing\");\n\t\tthis._writer = new ViewDowncastWriter(this.document);\n\t\tthis.addObserver(MutationObserver);\n\t\tthis.addObserver(FocusObserver);\n\t\tthis.addObserver(SelectionObserver);\n\t\tthis.addObserver(KeyObserver);\n\t\tthis.addObserver(FakeSelectionObserver);\n\t\tthis.addObserver(CompositionObserver);\n\t\tthis.addObserver(ArrowKeysObserver);\n\t\tthis.addObserver(InputObserver);\n\t\tthis.addObserver(TabObserver);\n\t\tinjectQuirksHandling(this);\n\t\tinjectUiElementHandling(this);\n\t\tthis.on(\"render\", () => {\n\t\t\tthis._render();\n\t\t\tthis.document.fire(\"layoutChanged\");\n\t\t\tthis._hasChangedSinceTheLastRendering = false;\n\t\t});\n\t\tthis.listenTo(this.document.selection, \"change\", () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t});\n\t\tthis.listenTo(this.document, \"change:isFocused\", () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t});\n\t\tif (env.isiOS) this.listenTo(this.document, \"blur\", (evt, data) => {\n\t\t\tif (!this.domConverter.mapDomToView(data.domEvent.relatedTarget)) this.domConverter._clearDomSelection();\n\t\t});\n\t\tthis.listenTo(this.document, \"mutations\", (evt, { mutations }) => {\n\t\t\tmutations.forEach((mutation) => this._renderer.markToSync(mutation.type, mutation.node));\n\t\t}, { priority: \"low\" });\n\t\tthis.listenTo(this.document, \"mutations\", () => {\n\t\t\tthis.forceRender();\n\t\t}, { priority: \"lowest\" });\n\t}\n\t/**\n\t* Attaches a DOM root element to the view element and enable all observers on that element.\n\t* Also {@link module:engine/view/renderer~ViewRenderer#markToSync mark element} to be synchronized\n\t* with the view what means that all child nodes will be removed and replaced with content of the view root.\n\t*\n\t* This method also will change view element name as the same as tag name of given dom root.\n\t* Name is always transformed to lower case.\n\t*\n\t* **Note:** Use {@link #detachDomRoot `detachDomRoot()`} to revert this action.\n\t*\n\t* @param domRoot DOM root element.\n\t* @param name Name of the root.\n\t*/\n\tattachDomRoot(domRoot, name = \"main\") {\n\t\tconst viewRoot = this.document.getRoot(name);\n\t\tviewRoot._name = domRoot.tagName.toLowerCase();\n\t\tconst initialDomRootAttributes = {};\n\t\tfor (const { name, value } of Array.from(domRoot.attributes)) {\n\t\t\tinitialDomRootAttributes[name] = value;\n\t\t\tif (name === \"class\") this._writer.addClass(value.split(\" \"), viewRoot);\n\t\t\telse if (!viewRoot.hasAttribute(name)) this._writer.setAttribute(name, value, viewRoot);\n\t\t}\n\t\tthis._initialDomRootAttributes.set(domRoot, initialDomRootAttributes);\n\t\tconst updateContenteditableAttribute = () => {\n\t\t\tthis._writer.setAttribute(\"contenteditable\", (!viewRoot.isReadOnly).toString(), viewRoot);\n\t\t\tif (viewRoot.isReadOnly) this._writer.addClass(\"ck-read-only\", viewRoot);\n\t\t\telse this._writer.removeClass(\"ck-read-only\", viewRoot);\n\t\t};\n\t\tupdateContenteditableAttribute();\n\t\tthis.domRoots.set(name, domRoot);\n\t\tthis.domConverter.bindElements(domRoot, viewRoot);\n\t\tthis._renderer.markToSync(\"children\", viewRoot);\n\t\tthis._renderer.markToSync(\"attributes\", viewRoot);\n\t\tthis._renderer.domDocuments.add(domRoot.ownerDocument);\n\t\tviewRoot.on(\"change:children\", (evt, node) => this._renderer.markToSync(\"children\", node));\n\t\tviewRoot.on(\"change:attributes\", (evt, node) => this._renderer.markToSync(\"attributes\", node));\n\t\tviewRoot.on(\"change:text\", (evt, node) => this._renderer.markToSync(\"text\", node));\n\t\tviewRoot.on(\"change:isReadOnly\", () => this.change(updateContenteditableAttribute));\n\t\tviewRoot.on(\"change\", () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t});\n\t\tfor (const observer of this._observers.values()) observer.observe(domRoot, name);\n\t}\n\t/**\n\t* Detaches a DOM root element from the view element and restores its attributes to the state before\n\t* {@link #attachDomRoot `attachDomRoot()`}.\n\t*\n\t* @param name Name of the root to detach.\n\t*/\n\tdetachDomRoot(name) {\n\t\tconst domRoot = this.domRoots.get(name);\n\t\tArray.from(domRoot.attributes).forEach(({ name }) => domRoot.removeAttribute(name));\n\t\tconst initialDomRootAttributes = this._initialDomRootAttributes.get(domRoot);\n\t\tfor (const attribute in initialDomRootAttributes) domRoot.setAttribute(attribute, initialDomRootAttributes[attribute]);\n\t\tthis.domRoots.delete(name);\n\t\tthis.domConverter.unbindDomElement(domRoot);\n\t\tfor (const observer of this._observers.values()) observer.stopObserving(domRoot);\n\t}\n\t/**\n\t* Gets DOM root element.\n\t*\n\t* @param name Name of the root.\n\t* @returns DOM root element instance.\n\t*/\n\tgetDomRoot(name = \"main\") {\n\t\treturn this.domRoots.get(name);\n\t}\n\t/**\n\t* Creates observer of the given type if not yet created, {@link module:engine/view/observer/observer~Observer#enable enables} it\n\t* and {@link module:engine/view/observer/observer~Observer#observe attaches} to all existing and future\n\t* {@link #domRoots DOM roots}.\n\t*\n\t* Note: Observers are recognized by their constructor (classes). A single observer will be instantiated and used only\n\t* when registered for the first time. This means that features and other components can register a single observer\n\t* multiple times without caring whether it has been already added or not.\n\t*\n\t* @param ObserverConstructor The constructor of an observer to add.\n\t* Should create an instance inheriting from {@link module:engine/view/observer/observer~Observer}.\n\t* @returns Added observer instance.\n\t*/\n\taddObserver(ObserverConstructor) {\n\t\tlet observer = this._observers.get(ObserverConstructor);\n\t\tif (observer) return observer;\n\t\tobserver = new ObserverConstructor(this);\n\t\tthis._observers.set(ObserverConstructor, observer);\n\t\tfor (const [name, domElement] of this.domRoots) observer.observe(domElement, name);\n\t\tobserver.enable();\n\t\treturn observer;\n\t}\n\t/**\n\t* Returns observer of the given type or `undefined` if such observer has not been added yet.\n\t*\n\t* @param ObserverConstructor The constructor of an observer to get.\n\t* @returns Observer instance or undefined.\n\t*/\n\tgetObserver(ObserverConstructor) {\n\t\treturn this._observers.get(ObserverConstructor);\n\t}\n\t/**\n\t* Disables all added observers.\n\t*/\n\tdisableObservers() {\n\t\tfor (const observer of this._observers.values()) observer.disable();\n\t}\n\t/**\n\t* Enables all added observers.\n\t*/\n\tenableObservers() {\n\t\tfor (const observer of this._observers.values()) observer.enable();\n\t}\n\t/**\n\t* Scrolls the page viewport and {@link #domRoots} with their ancestors to reveal the\n\t* caret, **if not already visible to the user**.\n\t*\n\t* **Note**: Calling this method fires the {@link module:engine/view/view~ViewScrollToTheSelectionEvent} event that\n\t* allows custom behaviors.\n\t*\n\t* @param options Additional configuration of the scrolling behavior.\n\t* @param options.viewportOffset A distance between the DOM selection and the viewport boundary to be maintained\n\t* while scrolling to the selection (default is 20px). Setting this value to `0` will reveal the selection precisely at\n\t* the viewport boundary.\n\t* @param options.ancestorOffset A distance between the DOM selection and scrollable DOM root ancestor(s) to be maintained\n\t* while scrolling to the selection (default is 20px). Setting this value to `0` will reveal the selection precisely at\n\t* the scrollable ancestor(s) boundary.\n\t* @param options.alignToTop When set `true`, the DOM selection will be aligned to the top of the viewport if not already visible\n\t* (see `forceScroll` to learn more).\n\t* @param options.forceScroll When set `true`, the DOM selection will be aligned to the top of the viewport and scrollable ancestors\n\t* whether it is already visible or not. This option will only work when `alignToTop` is `true`.\n\t*/\n\tscrollToTheSelection({ alignToTop, forceScroll, viewportOffset = 20, ancestorOffset = 20 } = {}) {\n\t\tconst range = this.document.selection.getFirstRange();\n\t\tif (!range) return;\n\t\tconst originalArgs = cloneDeep({\n\t\t\talignToTop,\n\t\t\tforceScroll,\n\t\t\tviewportOffset,\n\t\t\tancestorOffset\n\t\t});\n\t\tif (typeof viewportOffset === \"number\") viewportOffset = {\n\t\t\ttop: viewportOffset,\n\t\t\tbottom: viewportOffset,\n\t\t\tleft: viewportOffset,\n\t\t\tright: viewportOffset\n\t\t};\n\t\tconst options = {\n\t\t\ttarget: this.domConverter.viewRangeToDom(range),\n\t\t\tviewportOffset,\n\t\t\tancestorOffset,\n\t\t\talignToTop,\n\t\t\tforceScroll\n\t\t};\n\t\tthis.fire(\"scrollToTheSelection\", options, originalArgs);\n\t\tscrollViewportToShowTarget(options);\n\t}\n\t/**\n\t* It will focus DOM element representing {@link module:engine/view/editableelement~ViewEditableElement ViewEditableElement}\n\t* that is currently having selection inside.\n\t*/\n\tfocus() {\n\t\tif (!this.document.isFocused) {\n\t\t\tconst editable = this.document.selection.editableElement;\n\t\t\tif (editable) {\n\t\t\t\tthis.domConverter.focus(editable);\n\t\t\t\tthis.forceRender();\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* The `change()` method is the primary way of changing the view. You should use it to modify any node in the view tree.\n\t* It makes sure that after all changes are made the view is rendered to the DOM (assuming that the view will be changed\n\t* inside the callback). It prevents situations when the DOM is updated when the view state is not yet correct. It allows\n\t* to nest calls one inside another and still performs a single rendering after all those changes are made.\n\t* It also returns the return value of its callback.\n\t*\n\t* ```ts\n\t* const text = view.change( writer => {\n\t* \tconst newText = writer.createText( 'foo' );\n\t* \twriter.insert( position1, newText );\n\t*\n\t* \tview.change( writer => {\n\t* \t\twriter.insert( position2, writer.createText( 'bar' ) );\n\t* \t} );\n\t*\n\t* \twriter.remove( range );\n\t*\n\t* \treturn newText;\n\t* } );\n\t* ```\n\t*\n\t* When the outermost change block is done and rendering to the DOM is over the\n\t* {@link module:engine/view/view~EditingView#event:render `View#render`} event is fired.\n\t*\n\t* This method throws a `applying-view-changes-on-rendering` error when\n\t* the change block is used after rendering to the DOM has started.\n\t*\n\t* @param callback Callback function which may modify the view.\n\t* @returns Value returned by the callback.\n\t*/\n\tchange(callback) {\n\t\tif (this.isRenderingInProgress || this._postFixersInProgress)\n /**\n\t\t* Thrown when there is an attempt to make changes to the view tree when it is in incorrect state. This may\n\t\t* cause some unexpected behaviour and inconsistency between the DOM and the view.\n\t\t* This may be caused by:\n\t\t*\n\t\t* * calling {@link module:engine/view/view~EditingView#change} or {@link module:engine/view/view~EditingView#forceRender}\n\t\t* during rendering process,\n\t\t* * calling {@link module:engine/view/view~EditingView#change} or {@link module:engine/view/view~EditingView#forceRender}\n\t\t* inside of {@link module:engine/view/document~ViewDocument#registerPostFixer post-fixer function}.\n\t\t*\n\t\t* @error cannot-change-view-tree\n\t\t*/\n\t\tthrow new CKEditorError(\"cannot-change-view-tree\", this);\n\t\ttry {\n\t\t\tif (this._ongoingChange) return callback(this._writer);\n\t\t\tthis._ongoingChange = true;\n\t\t\tconst callbackResult = callback(this._writer);\n\t\t\tthis._ongoingChange = false;\n\t\t\tif (!this._renderingDisabled && this._hasChangedSinceTheLastRendering) {\n\t\t\t\tthis._postFixersInProgress = true;\n\t\t\t\tthis.document._callPostFixers(this._writer);\n\t\t\t\tthis._postFixersInProgress = false;\n\t\t\t\tthis.fire(\"render\");\n\t\t\t}\n\t\t\treturn callbackResult;\n\t\t} catch (err) {\n\t\t\tCKEditorError.rethrowUnexpectedError(err, this);\n\t\t}\n\t}\n\t/**\n\t* Forces rendering {@link module:engine/view/document~ViewDocument view document} to DOM. If any view changes are\n\t* currently in progress, rendering will start after all {@link #change change blocks} are processed.\n\t*\n\t* Note that this method is dedicated for special cases. All view changes should be wrapped in the {@link #change}\n\t* block and the view will automatically check whether it needs to render DOM or not.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `applying-view-changes-on-rendering` when\n\t* trying to re-render when rendering to DOM has already started.\n\t*/\n\tforceRender() {\n\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\tthis.getObserver(FocusObserver).flush();\n\t\tthis.change(() => {});\n\t}\n\t/**\n\t* Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t*/\n\tdestroy() {\n\t\tfor (const observer of this._observers.values()) observer.destroy();\n\t\tthis.document.destroy();\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Creates position at the given location. The location can be specified as:\n\t*\n\t* * a {@link module:engine/view/position~ViewPosition position},\n\t* * parent element and offset (offset defaults to `0`),\n\t* * parent element and `'end'` (sets position at the end of that element),\n\t* * {@link module:engine/view/item~ViewItem view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t*\n\t* This method is a shortcut to other constructors such as:\n\t*\n\t* * {@link #createPositionBefore},\n\t* * {@link #createPositionAfter},\n\t*\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~ViewItem view item}.\n\t*/\n\tcreatePositionAt(itemOrPosition, offset) {\n\t\treturn ViewPosition._createAt(itemOrPosition, offset);\n\t}\n\t/**\n\t* Creates a new position after given view item.\n\t*\n\t* @param item View item after which the position should be located.\n\t*/\n\tcreatePositionAfter(item) {\n\t\treturn ViewPosition._createAfter(item);\n\t}\n\t/**\n\t* Creates a new position before given view item.\n\t*\n\t* @param item View item before which the position should be located.\n\t*/\n\tcreatePositionBefore(item) {\n\t\treturn ViewPosition._createBefore(item);\n\t}\n\t/**\n\t* Creates a range spanning from `start` position to `end` position.\n\t*\n\t* **Note:** This factory method creates it's own {@link module:engine/view/position~ViewPosition} instances basing on passed values.\n\t*\n\t* @param start Start position.\n\t* @param end End position. If not set, range will be collapsed at `start` position.\n\t*/\n\tcreateRange(start, end) {\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Creates a range that starts before given {@link module:engine/view/item~ViewItem view item} and ends after it.\n\t*/\n\tcreateRangeOn(item) {\n\t\treturn ViewRange._createOn(item);\n\t}\n\t/**\n\t* Creates a range inside an {@link module:engine/view/element~ViewElement element} which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* @param element Element which is a parent for the range.\n\t*/\n\tcreateRangeIn(element) {\n\t\treturn ViewRange._createIn(element);\n\t}\n\tcreateSelection(...args) {\n\t\treturn new ViewSelection(...args);\n\t}\n\t/**\n\t* Disables or enables rendering. If the flag is set to `true` then the rendering will be disabled.\n\t* If the flag is set to `false` and if there was some change in the meantime, then the rendering action will be performed.\n\t*\n\t* @internal\n\t* @param flag A flag indicates whether the rendering should be disabled.\n\t*/\n\t_disableRendering(flag) {\n\t\tthis._renderingDisabled = flag;\n\t\tif (flag == false) this.change(() => {});\n\t}\n\t/**\n\t* Renders all changes. In order to avoid triggering the observers (e.g. selection) all observers are disabled\n\t* before rendering and re-enabled after that.\n\t*/\n\t_render() {\n\t\tthis.isRenderingInProgress = true;\n\t\tthis.disableObservers();\n\t\tthis._renderer.render();\n\t\tthis.enableObservers();\n\t\tthis.isRenderingInProgress = false;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\nvar ModelTypeCheckable = class {\n\t/* v8 ignore next -- @preserve */\n\tis() {\n\t\tthrow new Error(\"is() method is abstract\");\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/textproxy\n*/\n/**\n* `ModelTextProxy` represents a part of {@link module:engine/model/text~ModelText text node}.\n*\n* Since {@link module:engine/model/position~ModelPosition positions} can be placed between characters of a text node,\n* {@link module:engine/model/range~ModelRange ranges} may contain only parts of text nodes.\n* When {@link module:engine/model/range~ModelRange#getItems getting items}\n* contained in such range, we need to represent a part of that text node, since returning the whole text node would be incorrect.\n* `ModelTextProxy` solves this issue.\n*\n* `ModelTextProxy` has an API similar to {@link module:engine/model/text~ModelText Text} and allows to do\n* most of the common tasks performed on model nodes.\n*\n* **Note:** Some `ModelTextProxy` instances may represent whole text node, not just a part of it.\n* See {@link module:engine/model/textproxy~ModelTextProxy#isPartial}.\n*\n* **Note:** `ModelTextProxy` is not an instance of {@link module:engine/model/node~ModelNode node}. Keep this in mind when using it as a\n* parameter of methods.\n*\n* **Note:** `ModelTextProxy` is a readonly interface. If you want to perform changes on model data represented by a `ModelTextProxy`\n* use {@link module:engine/model/writer~ModelWriter model writer API}.\n*\n* **Note:** `ModelTextProxy` instances are created on the fly, basing on the current state of model. Because of this, it is\n* highly unrecommended to store references to `ModelTextProxy` instances. `ModelTextProxy` instances are not refreshed when\n* model changes, so they might get invalidated. Instead, consider creating {@link module:engine/model/liveposition~ModelLivePosition live\n* position}.\n*\n* `ModelTextProxy` instances are created by {@link module:engine/model/treewalker~ModelTreeWalker model tree walker}.\n* You should not need to create an instance of this class by your own.\n*/\nvar ModelTextProxy = class extends ModelTypeCheckable {\n\t/**\n\t* Text node which part is represented by this text proxy.\n\t*/\n\ttextNode;\n\t/**\n\t* Text data represented by this text proxy.\n\t*/\n\tdata;\n\t/**\n\t* Offset in {@link module:engine/model/textproxy~ModelTextProxy#textNode text node} from which the text proxy starts.\n\t*/\n\toffsetInText;\n\t/**\n\t* Creates a text proxy.\n\t*\n\t* @internal\n\t* @param textNode Text node which part is represented by this text proxy.\n\t* @param offsetInText Offset in {@link module:engine/model/textproxy~ModelTextProxy#textNode text node} from which the text proxy\n\t* starts.\n\t* @param length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t*/\n\tconstructor(textNode, offsetInText, length) {\n\t\tsuper();\n\t\tthis.textNode = textNode;\n\t\tif (offsetInText < 0 || offsetInText > textNode.offsetSize)\n /**\n\t\t* Given `offsetInText` value is incorrect.\n\t\t*\n\t\t* @error model-textproxy-wrong-offsetintext\n\t\t*/\n\t\tthrow new CKEditorError(\"model-textproxy-wrong-offsetintext\", this);\n\t\tif (length < 0 || offsetInText + length > textNode.offsetSize)\n /**\n\t\t* Given `length` value is incorrect.\n\t\t*\n\t\t* @error model-textproxy-wrong-length\n\t\t*/\n\t\tthrow new CKEditorError(\"model-textproxy-wrong-length\", this);\n\t\tthis.data = textNode.data.substring(offsetInText, offsetInText + length);\n\t\tthis.offsetInText = offsetInText;\n\t}\n\t/**\n\t* Offset at which this text proxy starts in it's parent.\n\t*\n\t* @see module:engine/model/node~ModelNode#startOffset\n\t*/\n\tget startOffset() {\n\t\treturn this.textNode.startOffset !== null ? this.textNode.startOffset + this.offsetInText : null;\n\t}\n\t/**\n\t* Offset size of this text proxy. Equal to the number of characters represented by the text proxy.\n\t*\n\t* @see module:engine/model/node~ModelNode#offsetSize\n\t*/\n\tget offsetSize() {\n\t\treturn this.data.length;\n\t}\n\t/**\n\t* Offset at which this text proxy ends in it's parent.\n\t*\n\t* @see module:engine/model/node~ModelNode#endOffset\n\t*/\n\tget endOffset() {\n\t\treturn this.startOffset !== null ? this.startOffset + this.offsetSize : null;\n\t}\n\t/**\n\t* Flag indicating whether `ModelTextProxy` instance covers only part of the original\n\t* {@link module:engine/model/text~ModelText text node} (`true`) or the whole text node (`false`).\n\t*\n\t* This is `false` when text proxy starts at the very beginning of\n\t* {@link module:engine/model/textproxy~ModelTextProxy#textNode textNode}\n\t* ({@link module:engine/model/textproxy~ModelTextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t* text node size.\n\t*/\n\tget isPartial() {\n\t\treturn this.offsetSize !== this.textNode.offsetSize;\n\t}\n\t/**\n\t* Parent of this text proxy, which is same as parent of text node represented by this text proxy.\n\t*/\n\tget parent() {\n\t\treturn this.textNode.parent;\n\t}\n\t/**\n\t* Root of this text proxy, which is same as root of text node represented by this text proxy.\n\t*/\n\tget root() {\n\t\treturn this.textNode.root;\n\t}\n\t/**\n\t* Gets path to this text proxy.\n\t*\n\t* @see module:engine/model/node~ModelNode#getPath\n\t*/\n\tgetPath() {\n\t\tconst path = this.textNode.getPath();\n\t\tif (path.length > 0) path[path.length - 1] += this.offsetInText;\n\t\treturn path;\n\t}\n\t/**\n\t* Returns ancestors array of this text proxy.\n\t*\n\t* @param options Options object.\n\t* @param options.includeSelf When set to `true` this text proxy will be also included in parent's array.\n\t* @param options.parentFirst When set to `true`, array will be sorted from text proxy parent to root element,\n\t* otherwise root element will be the first item in the array.\n\t* @returns Array with ancestors.\n\t*/\n\tgetAncestors(options = {}) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\t\twhile (parent) {\n\t\t\tancestors[options.parentFirst ? \"push\" : \"unshift\"](parent);\n\t\t\tparent = parent.parent;\n\t\t}\n\t\treturn ancestors;\n\t}\n\t/**\n\t* Checks if this text proxy has an attribute for given key.\n\t*\n\t* @param key Key of attribute to check.\n\t* @returns `true` if attribute with given key is set on text proxy, `false` otherwise.\n\t*/\n\thasAttribute(key) {\n\t\treturn this.textNode.hasAttribute(key);\n\t}\n\t/**\n\t* Gets an attribute value for given key or `undefined` if that attribute is not set on text proxy.\n\t*\n\t* @param key Key of attribute to look for.\n\t* @returns Attribute value or `undefined`.\n\t*/\n\tgetAttribute(key) {\n\t\treturn this.textNode.getAttribute(key);\n\t}\n\t/**\n\t* Returns iterator that iterates over this node's attributes. Attributes are returned as arrays containing two\n\t* items. First one is attribute key and second is attribute value.\n\t*\n\t* This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t*/\n\tgetAttributes() {\n\t\treturn this.textNode.getAttributes();\n\t}\n\t/**\n\t* Returns iterator that iterates over this node's attribute keys.\n\t*/\n\tgetAttributeKeys() {\n\t\treturn this.textNode.getAttributeKeys();\n\t}\n};\nModelTextProxy.prototype.is = function(type) {\n\treturn type === \"$textProxy\" || type === \"model:$textProxy\" || type === \"textProxy\" || type === \"model:textProxy\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Position iterator class. It allows to iterate forward and backward over the document.\n*/\nvar ModelTreeWalker = class {\n\t/**\n\t* Walking direction. Defaults `'forward'`.\n\t*/\n\tdirection;\n\t/**\n\t* Iterator boundaries.\n\t*\n\t* When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t* on the start of boundary, then `{ done: true }` is returned.\n\t*\n\t* If boundaries are not defined they are set before first and after last child of the root node.\n\t*/\n\tboundaries;\n\t/**\n\t* Flag indicating whether all consecutive characters with the same attributes should be\n\t* returned as one {@link module:engine/model/textproxy~ModelTextProxy} (`true`) or one by one (`false`).\n\t*/\n\tsingleCharacters;\n\t/**\n\t* Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t* iterated node will not be returned along with `elementEnd` tag.\n\t*/\n\tshallow;\n\t/**\n\t* Flag indicating whether iterator should ignore `elementEnd` tags. If the option is true walker will not\n\t* return a parent node of the start position. If this option is `true` each {@link module:engine/model/element~ModelElement} will\n\t* be returned once, while if the option is `false` they might be returned twice:\n\t* for `'elementStart'` and `'elementEnd'`.\n\t*/\n\tignoreElementEnd;\n\t/**\n\t* Iterator position. This is always static position, even if the initial position was a\n\t* {@link module:engine/model/liveposition~ModelLivePosition live position}. If start position is not defined then position depends\n\t* on {@link #direction}. If direction is `'forward'` position starts form the beginning, when direction\n\t* is `'backward'` position starts from the end.\n\t*/\n\t_position;\n\t/**\n\t* Start boundary cached for optimization purposes.\n\t*/\n\t_boundaryStartParent;\n\t/**\n\t* End boundary cached for optimization purposes.\n\t*/\n\t_boundaryEndParent;\n\t/**\n\t* Parent of the most recently visited node. Cached for optimization purposes.\n\t*/\n\t_visitedParent;\n\t/**\n\t* Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t*\n\t* @param options Object with configuration.\n\t*/\n\tconstructor(options) {\n\t\tif (!options || !options.boundaries && !options.startPosition)\n /**\n\t\t* Neither boundaries nor starting position of a `TreeWalker` have been defined.\n\t\t*\n\t\t* @error model-tree-walker-no-start-position\n\t\t*/\n\t\tthrow new CKEditorError(\"model-tree-walker-no-start-position\", null);\n\t\tconst direction = options.direction || \"forward\";\n\t\tif (direction != \"forward\" && direction != \"backward\")\n /**\n\t\t* Only `backward` and `forward` direction allowed.\n\t\t*\n\t\t* @error model-tree-walker-unknown-direction\n\t\t*/\n\t\tthrow new CKEditorError(\"model-tree-walker-unknown-direction\", options, { direction });\n\t\tthis.direction = direction;\n\t\tthis.boundaries = options.boundaries || null;\n\t\tif (options.startPosition) this._position = options.startPosition.clone();\n\t\telse this._position = ModelPosition._createAt(this.boundaries[this.direction == \"backward\" ? \"end\" : \"start\"]);\n\t\tthis.position.stickiness = \"toNone\";\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\t\tthis.shallow = !!options.shallow;\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\t\tthis._visitedParent = this.position.parent;\n\t}\n\t/**\n\t* Iterable interface.\n\t*\n\t* @returns {Iterable.<module:engine/model/treewalker~ModelTreeWalkerValue>}\n\t*/\n\t[Symbol.iterator]() {\n\t\treturn this;\n\t}\n\t/**\n\t* Iterator position. This is always static position, even if the initial position was a\n\t* {@link module:engine/model/liveposition~ModelLivePosition live position}. If start position is not defined then position depends\n\t* on {@link #direction}. If direction is `'forward'` position starts form the beginning, when direction\n\t* is `'backward'` position starts from the end.\n\t*/\n\tget position() {\n\t\treturn this._position;\n\t}\n\t/**\n\t* Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t*\n\t* For example:\n\t*\n\t* ```ts\n\t* walker.skip( value => value.type == 'text' ); // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t* walker.skip( () => true ); // Move the position to the end: <paragraph>[]foo</paragraph> -> <paragraph>foo</paragraph>[]\n\t* walker.skip( () => false ); // Do not move the position.\n\t* ```\n\t*\n\t* @param skip Callback function. Gets {@link module:engine/model/treewalker~ModelTreeWalkerValue} and should\n\t* return `true` if the value should be skipped or `false` if not.\n\t*/\n\tskip(skip) {\n\t\tlet done, value, prevPosition, prevVisitedParent;\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\t\t\tprevVisitedParent = this._visitedParent;\n\t\t\t({done, value} = this.next());\n\t\t} while (!done && skip(value));\n\t\tif (!done) {\n\t\t\tthis._position = prevPosition;\n\t\t\tthis._visitedParent = prevVisitedParent;\n\t\t}\n\t}\n\t/**\n\t* Moves tree walker {@link #position} to provided `position`. Tree walker will\n\t* continue traversing from that position.\n\t*\n\t* Note: in contrary to {@link ~ModelTreeWalker#skip}, this method does not iterate over the nodes along the way.\n\t* It simply sets the current tree walker position to a new one.\n\t* From the performance standpoint, it is better to use {@link ~ModelTreeWalker#jumpTo} rather than {@link ~ModelTreeWalker#skip}.\n\t*\n\t* If the provided position is before the start boundary, the position will be\n\t* set to the start boundary. If the provided position is after the end boundary,\n\t* the position will be set to the end boundary.\n\t* This is done to prevent the treewalker from traversing outside the boundaries.\n\t*\n\t* @param position Position to jump to.\n\t*/\n\tjumpTo(position) {\n\t\tif (this._boundaryStartParent && position.isBefore(this.boundaries.start)) position = this.boundaries.start;\n\t\telse if (this._boundaryEndParent && position.isAfter(this.boundaries.end)) position = this.boundaries.end;\n\t\tthis._position = position.clone();\n\t\tthis._visitedParent = position.parent;\n\t}\n\t/**\n\t* Gets the next tree walker's value.\n\t*/\n\tnext() {\n\t\tif (this.direction == \"forward\") return this._next();\n\t\telse return this._previous();\n\t}\n\t/**\n\t* Makes a step forward in model. Moves the {@link #position} to the next position and returns the encountered value.\n\t*/\n\t_next() {\n\t\tconst previousPosition = this.position;\n\t\tconst position = this.position.clone();\n\t\tconst parent = this._visitedParent;\n\t\tif (parent.parent === null && position.offset === parent.maxOffset) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tif (parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tconst textNodeAtPosition = getTextNodeAtPosition(position, parent);\n\t\tconst node = textNodeAtPosition || getNodeAfterPosition(position, parent, textNodeAtPosition);\n\t\tif (node && node.is(\"model:element\")) {\n\t\t\tif (!this.shallow) {\n\t\t\t\tposition.path.push(0);\n\t\t\t\tthis._visitedParent = node;\n\t\t\t} else {\n\t\t\t\tif (this.boundaries && this.boundaries.end.isBefore(position)) return {\n\t\t\t\t\tdone: true,\n\t\t\t\t\tvalue: void 0\n\t\t\t\t};\n\t\t\t\tposition.offset++;\n\t\t\t}\n\t\t\tthis._position = position;\n\t\t\treturn formatReturnValue(\"elementStart\", node, previousPosition, position, 1);\n\t\t}\n\t\tif (node && node.is(\"model:$text\")) {\n\t\t\tlet charactersCount;\n\t\t\tif (this.singleCharacters) charactersCount = 1;\n\t\t\telse {\n\t\t\t\tlet offset = node.endOffset;\n\t\t\t\tif (this._boundaryEndParent == parent && this.boundaries.end.offset < offset) offset = this.boundaries.end.offset;\n\t\t\t\tcharactersCount = offset - position.offset;\n\t\t\t}\n\t\t\tconst offsetInTextNode = position.offset - node.startOffset;\n\t\t\tconst item = new ModelTextProxy(node, offsetInTextNode, charactersCount);\n\t\t\tposition.offset += charactersCount;\n\t\t\tthis._position = position;\n\t\t\treturn formatReturnValue(\"text\", item, previousPosition, position, charactersCount);\n\t\t}\n\t\tposition.path.pop();\n\t\tposition.offset++;\n\t\tthis._position = position;\n\t\tthis._visitedParent = parent.parent;\n\t\tif (this.ignoreElementEnd) return this._next();\n\t\treturn formatReturnValue(\"elementEnd\", parent, previousPosition, position);\n\t}\n\t/**\n\t* Makes a step backward in model. Moves the {@link #position} to the previous position and returns the encountered value.\n\t*/\n\t_previous() {\n\t\tconst previousPosition = this.position;\n\t\tconst position = this.position.clone();\n\t\tconst parent = this._visitedParent;\n\t\tif (parent.parent === null && position.offset === 0) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tif (parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tconst positionParent = position.parent;\n\t\tconst textNodeAtPosition = getTextNodeAtPosition(position, positionParent);\n\t\tconst node = textNodeAtPosition || getNodeBeforePosition(position, positionParent, textNodeAtPosition);\n\t\tif (node && node.is(\"model:element\")) {\n\t\t\tposition.offset--;\n\t\t\tif (this.shallow) {\n\t\t\t\tthis._position = position;\n\t\t\t\treturn formatReturnValue(\"elementStart\", node, previousPosition, position, 1);\n\t\t\t}\n\t\t\tposition.path.push(node.maxOffset);\n\t\t\tthis._position = position;\n\t\t\tthis._visitedParent = node;\n\t\t\tif (this.ignoreElementEnd) return this._previous();\n\t\t\treturn formatReturnValue(\"elementEnd\", node, previousPosition, position);\n\t\t}\n\t\tif (node && node.is(\"model:$text\")) {\n\t\t\tlet charactersCount;\n\t\t\tif (this.singleCharacters) charactersCount = 1;\n\t\t\telse {\n\t\t\t\tlet offset = node.startOffset;\n\t\t\t\tif (this._boundaryStartParent == parent && this.boundaries.start.offset > offset) offset = this.boundaries.start.offset;\n\t\t\t\tcharactersCount = position.offset - offset;\n\t\t\t}\n\t\t\tconst offsetInTextNode = position.offset - node.startOffset;\n\t\t\tconst item = new ModelTextProxy(node, offsetInTextNode - charactersCount, charactersCount);\n\t\t\tposition.offset -= charactersCount;\n\t\t\tthis._position = position;\n\t\t\treturn formatReturnValue(\"text\", item, previousPosition, position, charactersCount);\n\t\t}\n\t\tposition.path.pop();\n\t\tthis._position = position;\n\t\tthis._visitedParent = parent.parent;\n\t\treturn formatReturnValue(\"elementStart\", parent, previousPosition, position, 1);\n\t}\n};\nfunction formatReturnValue(type, item, previousPosition, nextPosition, length) {\n\treturn {\n\t\tdone: false,\n\t\tvalue: {\n\t\t\ttype,\n\t\t\titem,\n\t\t\tpreviousPosition,\n\t\t\tnextPosition,\n\t\t\tlength\n\t\t}\n\t};\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/position\n*/\n/**\n* Represents a position in the model tree.\n*\n* A position is represented by its {@link module:engine/model/position~ModelPosition#root} and\n* a {@link module:engine/model/position~ModelPosition#path} in that root.\n*\n* You can create position instances via its constructor or the `createPosition*()` factory methods of\n* {@link module:engine/model/model~Model} and {@link module:engine/model/writer~ModelWriter}.\n*\n* **Note:** Position is based on offsets, not indexes. This means that a position between two text nodes\n* `foo` and `bar` has offset `3`, not `1`. See {@link module:engine/model/position~ModelPosition#path} for more information.\n*\n* Since a position in the model is represented by a {@link module:engine/model/position~ModelPosition#root position root} and\n* {@link module:engine/model/position~ModelPosition#path position path} it is possible to create positions placed in non-existing places.\n* This requirement is important for operational transformation algorithms.\n*\n* Also, {@link module:engine/model/operation/operation~Operation operations}\n* kept in the {@link module:engine/model/document~ModelDocument#history document history}\n* are storing positions (and ranges) which were correct when those operations were applied, but may not be correct\n* after the document has changed.\n*\n* When changes are applied to the model, it may also happen that {@link module:engine/model/position~ModelPosition#parent position parent}\n* will change even if position path has not changed. Keep in mind, that if a position leads to non-existing element,\n* {@link module:engine/model/position~ModelPosition#parent} and some other properties and methods will throw errors.\n*\n* In most cases, position with wrong path is caused by an error in code, but it is sometimes needed, as described above.\n*/\nvar ModelPosition = class ModelPosition extends ModelTypeCheckable {\n\t/**\n\t* Root of the position path.\n\t*/\n\troot;\n\t/**\n\t* Position of the node in the tree. **Path contains offsets, not indexes.**\n\t*\n\t* Position can be placed before, after or in a {@link module:engine/model/node~ModelNode node} if that node has\n\t* {@link module:engine/model/node~ModelNode#offsetSize} greater than `1`. Items in position path are\n\t* {@link module:engine/model/node~ModelNode#startOffset starting offsets} of position ancestors, starting from direct root children,\n\t* down to the position offset in it's parent.\n\t*\n\t* ```\n\t* ROOT\n\t* |- P before: [ 0 ] after: [ 1 ]\n\t* |- UL before: [ 1 ] after: [ 2 ]\n\t* |- LI before: [ 1, 0 ] after: [ 1, 1 ]\n\t* | |- foo before: [ 1, 0, 0 ] after: [ 1, 0, 3 ]\n\t* |- LI before: [ 1, 1 ] after: [ 1, 2 ]\n\t* |- bar before: [ 1, 1, 0 ] after: [ 1, 1, 3 ]\n\t* ```\n\t*\n\t* `foo` and `bar` are representing {@link module:engine/model/text~ModelText text nodes}. Since text nodes has offset size\n\t* greater than `1` you can place position offset between their start and end:\n\t*\n\t* ```\n\t* ROOT\n\t* |- P\n\t* |- UL\n\t* |- LI\n\t* | |- f^o|o ^ has path: [ 1, 0, 1 ] | has path: [ 1, 0, 2 ]\n\t* |- LI\n\t* |- b^a|r ^ has path: [ 1, 1, 1 ] | has path: [ 1, 1, 2 ]\n\t* ```\n\t*/\n\tpath;\n\t/**\n\t* Position stickiness. See {@link module:engine/model/position~ModelPositionStickiness}.\n\t*/\n\tstickiness;\n\t/**\n\t* Creates a position.\n\t*\n\t* @param root Root of the position.\n\t* @param path Position path. See {@link module:engine/model/position~ModelPosition#path}.\n\t* @param stickiness Position stickiness. See {@link module:engine/model/position~ModelPositionStickiness}.\n\t*/\n\tconstructor(root, path, stickiness = \"toNone\") {\n\t\tsuper();\n\t\tif (!root.is(\"element\") && !root.is(\"documentFragment\"))\n /**\n\t\t* Position root is invalid.\n\t\t*\n\t\t* Positions can only be anchored in elements or document fragments.\n\t\t*\n\t\t* @error model-position-root-invalid\n\t\t*/\n\t\tthrow new CKEditorError(\"model-position-root-invalid\", root);\n\t\tif (!Array.isArray(path) || path.length === 0)\n /**\n\t\t* Position path must be an array with at least one item.\n\t\t*\n\t\t* @error model-position-path-incorrect-format\n\t\t* @param {Array.<number>} path A path to the position.\n\t\t*/\n\t\tthrow new CKEditorError(\"model-position-path-incorrect-format\", root, { path });\n\t\tif (root.is(\"rootElement\")) path = path.slice();\n\t\telse {\n\t\t\tpath = [...root.getPath(), ...path];\n\t\t\troot = root.root;\n\t\t}\n\t\tthis.root = root;\n\t\tthis.path = path;\n\t\tthis.stickiness = stickiness;\n\t}\n\t/**\n\t* Offset at which this position is located in its {@link module:engine/model/position~ModelPosition#parent parent}. It is equal\n\t* to the last item in position {@link module:engine/model/position~ModelPosition#path path}.\n\t*\n\t* @type {Number}\n\t*/\n\tget offset() {\n\t\treturn this.path[this.path.length - 1];\n\t}\n\tset offset(newOffset) {\n\t\tthis.path[this.path.length - 1] = newOffset;\n\t}\n\t/**\n\t* Parent element of this position.\n\t*\n\t* Keep in mind that `parent` value is calculated when the property is accessed.\n\t* If {@link module:engine/model/position~ModelPosition#path position path}\n\t* leads to a non-existing element, `parent` property will throw error.\n\t*\n\t* Also it is a good idea to cache `parent` property if it is used frequently in an algorithm (i.e. in a long loop).\n\t*/\n\tget parent() {\n\t\tlet parent = this.root;\n\t\tfor (let i = 0; i < this.path.length - 1; i++) {\n\t\t\tparent = parent.getChildAtOffset(this.path[i]);\n\t\t\tif (!parent)\n /**\n\t\t\t* The position's path is incorrect. This means that a position does not point to\n\t\t\t* a correct place in the tree and hence, some of its methods and getters cannot work correctly.\n\t\t\t*\n\t\t\t* **Note**: Unlike DOM and view positions, in the model, the\n\t\t\t* {@link module:engine/model/position~ModelPosition#parent position's parent} is always an element or a document fragment.\n\t\t\t* The last offset in the\n\t\t\t* {@link module:engine/model/position~ModelPosition#path position's path} is the point in this element\n\t\t\t* where this position points.\n\t\t\t*\n\t\t\t* Read more about model positions and offsets in\n\t\t\t* the {@glink framework/architecture/editing-engine#indexes-and-offsets Editing engine architecture} guide.\n\t\t\t*\n\t\t\t* @error model-position-path-incorrect\n\t\t\t* @param {module:engine/model/position~ModelPosition} position The incorrect position.\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"model-position-path-incorrect\", this, { position: this });\n\t\t}\n\t\tif (parent.is(\"$text\")) throw new CKEditorError(\"model-position-path-incorrect\", this, { position: this });\n\t\treturn parent;\n\t}\n\t/**\n\t* Position {@link module:engine/model/position~ModelPosition#offset offset} converted to an index in position's parent node. It is\n\t* equal to the {@link module:engine/model/node~ModelNode#index index} of a node after this position. If position is placed\n\t* in text node, position index is equal to the index of that text node.\n\t*/\n\tget index() {\n\t\treturn this.parent.offsetToIndex(this.offset);\n\t}\n\t/**\n\t* Returns {@link module:engine/model/text~ModelText text node} instance in which this position is placed or `null` if this\n\t* position is not in a text node.\n\t*/\n\tget textNode() {\n\t\treturn getTextNodeAtPosition(this, this.parent);\n\t}\n\t/**\n\t* Node directly after this position. Returns `null` if this position is at the end of its parent, or if it is in a text node.\n\t*/\n\tget nodeAfter() {\n\t\tconst parent = this.parent;\n\t\treturn getNodeAfterPosition(this, parent, getTextNodeAtPosition(this, parent));\n\t}\n\t/**\n\t* Node directly before this position. Returns `null` if this position is at the start of its parent, or if it is in a text node.\n\t*/\n\tget nodeBefore() {\n\t\tconst parent = this.parent;\n\t\treturn getNodeBeforePosition(this, parent, getTextNodeAtPosition(this, parent));\n\t}\n\t/**\n\t* Is `true` if position is at the beginning of its {@link module:engine/model/position~ModelPosition#parent parent}, `false` otherwise.\n\t*/\n\tget isAtStart() {\n\t\treturn this.offset === 0;\n\t}\n\t/**\n\t* Is `true` if position is at the end of its {@link module:engine/model/position~ModelPosition#parent parent}, `false` otherwise.\n\t*/\n\tget isAtEnd() {\n\t\treturn this.offset == this.parent.maxOffset;\n\t}\n\t/**\n\t* Checks whether the position is valid in current model tree, that is whether it points to an existing place in the model.\n\t*/\n\tisValid() {\n\t\tif (this.offset < 0) return false;\n\t\tlet parent = this.root;\n\t\tfor (let i = 0; i < this.path.length - 1; i++) {\n\t\t\tparent = parent.getChildAtOffset(this.path[i]);\n\t\t\tif (!parent) return false;\n\t\t}\n\t\treturn this.offset <= parent.maxOffset;\n\t}\n\t/**\n\t* Checks whether this position is before or after given position.\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*/\n\tcompareWith(otherPosition) {\n\t\tif (this.root != otherPosition.root) return \"different\";\n\t\tconst result = compareArrays(this.path, otherPosition.path);\n\t\tswitch (result) {\n\t\t\tcase \"same\": return \"same\";\n\t\t\tcase \"prefix\": return \"before\";\n\t\t\tcase \"extension\": return \"after\";\n\t\t\tdefault: return this.path[result] < otherPosition.path[result] ? \"before\" : \"after\";\n\t\t}\n\t}\n\t/**\n\t* Gets the farthest position which matches the callback using\n\t* {@link module:engine/model/treewalker~ModelTreeWalker TreeWalker}.\n\t*\n\t* For example:\n\t*\n\t* ```ts\n\t* getLastMatchingPosition( value => value.type == 'text' );\n\t* // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t*\n\t* getLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } );\n\t* // <paragraph>foo[]</paragraph> -> <paragraph>[]foo</paragraph>\n\t*\n\t* getLastMatchingPosition( value => false );\n\t* // Do not move the position.\n\t* ```\n\t*\n\t* @param skip Callback function. Gets {@link module:engine/model/treewalker~ModelTreeWalkerValue} and should\n\t* return `true` if the value should be skipped or `false` if not.\n\t* @param options Object with configuration options. See {@link module:engine/model/treewalker~ModelTreeWalker}.\n\t*\n\t* @returns The position after the last item which matches the `skip` callback test.\n\t*/\n\tgetLastMatchingPosition(skip, options = {}) {\n\t\toptions.startPosition = this;\n\t\tconst treeWalker = new ModelTreeWalker(options);\n\t\ttreeWalker.skip(skip);\n\t\treturn treeWalker.position;\n\t}\n\t/**\n\t* Returns a path to this position's parent. Parent path is equal to position\n\t* {@link module:engine/model/position~ModelPosition#path path} but without the last item.\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*\n\t* @returns Path to the parent.\n\t*/\n\tgetParentPath() {\n\t\treturn this.path.slice(0, -1);\n\t}\n\t/**\n\t* Returns ancestors array of this position, that is this position's parent and its ancestors.\n\t*\n\t* @returns Array with ancestors.\n\t*/\n\tgetAncestors() {\n\t\tconst parent = this.parent;\n\t\tif (parent.is(\"documentFragment\")) return [parent];\n\t\telse return parent.getAncestors({ includeSelf: true });\n\t}\n\t/**\n\t* Returns the parent element of the given name. Returns null if the position is not inside the desired parent.\n\t*\n\t* @param parentName The name of the parent element to find.\n\t*/\n\tfindAncestor(parentName) {\n\t\tconst parent = this.parent;\n\t\tif (parent.is(\"element\")) return parent.findAncestor(parentName, { includeSelf: true });\n\t\treturn null;\n\t}\n\t/**\n\t* Returns the slice of two position {@link #path paths} which is identical. The {@link #root roots}\n\t* of these two paths must be identical.\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*\n\t* @param position The second position.\n\t* @returns The common path.\n\t*/\n\tgetCommonPath(position) {\n\t\tif (this.root != position.root) return [];\n\t\tconst cmp = compareArrays(this.path, position.path);\n\t\tconst diffAt = typeof cmp == \"string\" ? Math.min(this.path.length, position.path.length) : cmp;\n\t\treturn this.path.slice(0, diffAt);\n\t}\n\t/**\n\t* Returns an {@link module:engine/model/element~ModelElement} or {@link module:engine/model/documentfragment~ModelDocumentFragment}\n\t* which is a common ancestor of both positions. The {@link #root roots} of these two positions must be identical.\n\t*\n\t* @param position The second position.\n\t*/\n\tgetCommonAncestor(position) {\n\t\tconst ancestorsA = this.getAncestors();\n\t\tconst ancestorsB = position.getAncestors();\n\t\tlet i = 0;\n\t\twhile (ancestorsA[i] == ancestorsB[i] && ancestorsA[i]) i++;\n\t\treturn i === 0 ? null : ancestorsA[i - 1];\n\t}\n\t/**\n\t* Returns a new instance of `Position`, that has same {@link #parent parent} but it's offset\n\t* is shifted by `shift` value (can be a negative value).\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*\n\t* @param shift Offset shift. Can be a negative value.\n\t* @returns Shifted position.\n\t*/\n\tgetShiftedBy(shift) {\n\t\tconst shifted = this.clone();\n\t\tconst offset = shifted.offset + shift;\n\t\tshifted.offset = offset < 0 ? 0 : offset;\n\t\treturn shifted;\n\t}\n\t/**\n\t* Checks whether this position is after given position.\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*\n\t* @see module:engine/model/position~ModelPosition#isBefore\n\t* @param otherPosition Position to compare with.\n\t* @returns True if this position is after given position.\n\t*/\n\tisAfter(otherPosition) {\n\t\treturn this.compareWith(otherPosition) == \"after\";\n\t}\n\t/**\n\t* Checks whether this position is before given position.\n\t*\n\t* **Note:** watch out when using negation of the value returned by this method, because the negation will also\n\t* be `true` if positions are in different roots and you might not expect this. You should probably use\n\t* `a.isAfter( b ) || a.isEqual( b )` or `!a.isBefore( p ) && a.root == b.root` in most scenarios. If your\n\t* condition uses multiple `isAfter` and `isBefore` checks, build them so they do not use negated values, i.e.:\n\t*\n\t* ```ts\n\t* if ( a.isBefore( b ) && c.isAfter( d ) ) {\n\t* \t// do A.\n\t* } else {\n\t* \t// do B.\n\t* }\n\t* ```\n\t*\n\t* or, if you have only one if-branch:\n\t*\n\t* ```ts\n\t* if ( !( a.isBefore( b ) && c.isAfter( d ) ) {\n\t* \t// do B.\n\t* }\n\t* ```\n\t*\n\t* rather than:\n\t*\n\t* ```ts\n\t* if ( !a.isBefore( b ) || && !c.isAfter( d ) ) {\n\t* \t// do B.\n\t* } else {\n\t* \t// do A.\n\t* }\n\t* ```\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*\n\t* @param otherPosition Position to compare with.\n\t* @returns True if this position is before given position.\n\t*/\n\tisBefore(otherPosition) {\n\t\treturn this.compareWith(otherPosition) == \"before\";\n\t}\n\t/**\n\t* Checks whether this position is equal to given position.\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*\n\t* @param otherPosition Position to compare with.\n\t* @returns True if positions are same.\n\t*/\n\tisEqual(otherPosition) {\n\t\treturn this.compareWith(otherPosition) == \"same\";\n\t}\n\t/**\n\t* Checks whether this position is touching given position. Positions touch when there are no text nodes\n\t* or empty nodes in a range between them. Technically, those positions are not equal but in many cases\n\t* they are very similar or even indistinguishable.\n\t*\n\t* @param otherPosition Position to compare with.\n\t* @returns True if positions touch.\n\t*/\n\tisTouching(otherPosition) {\n\t\tif (this.root !== otherPosition.root) return false;\n\t\tconst commonLevel = Math.min(this.path.length, otherPosition.path.length);\n\t\tfor (let level = 0; level < commonLevel; level++) {\n\t\t\tconst diff = this.path[level] - otherPosition.path[level];\n\t\t\tif (diff < -1 || diff > 1) return false;\n\t\t\telse if (diff === 1) return checkTouchingBranch(otherPosition, this, level);\n\t\t\telse if (diff === -1) return checkTouchingBranch(this, otherPosition, level);\n\t\t}\n\t\tif (this.path.length === otherPosition.path.length) return true;\n\t\telse if (this.path.length > otherPosition.path.length) return checkOnlyZeroes(this.path, commonLevel);\n\t\telse return checkOnlyZeroes(otherPosition.path, commonLevel);\n\t}\n\t/**\n\t* Checks if two positions are in the same parent.\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*\n\t* @param position Position to compare with.\n\t* @returns `true` if positions have the same parent, `false` otherwise.\n\t*/\n\thasSameParentAs(position) {\n\t\tif (this.root !== position.root) return false;\n\t\tconst thisParentPath = this.getParentPath();\n\t\tconst posParentPath = position.getParentPath();\n\t\treturn compareArrays(thisParentPath, posParentPath) == \"same\";\n\t}\n\t/**\n\t* Returns a copy of this position that is transformed by given `operation`.\n\t*\n\t* The new position's parameters are updated accordingly to the effect of the `operation`.\n\t*\n\t* For example, if `n` nodes are inserted before the position, the returned position {@link ~ModelPosition#offset} will be\n\t* increased by `n`. If the position was in a merged element, it will be accordingly moved to the new element, etc.\n\t*\n\t* This method is safe to use it on non-existing positions (for example during operational transformation).\n\t*\n\t* @param operation Operation to transform by.\n\t* @returns Transformed position.\n\t*/\n\tgetTransformedByOperation(operation) {\n\t\tlet result;\n\t\tswitch (operation.type) {\n\t\t\tcase \"insert\":\n\t\t\t\tresult = this._getTransformedByInsertOperation(operation);\n\t\t\t\tbreak;\n\t\t\tcase \"move\":\n\t\t\tcase \"remove\":\n\t\t\tcase \"reinsert\":\n\t\t\t\tresult = this._getTransformedByMoveOperation(operation);\n\t\t\t\tbreak;\n\t\t\tcase \"split\":\n\t\t\t\tresult = this._getTransformedBySplitOperation(operation);\n\t\t\t\tbreak;\n\t\t\tcase \"merge\":\n\t\t\t\tresult = this._getTransformedByMergeOperation(operation);\n\t\t\t\tbreak;\n\t\t\tcase \"detach\":\n\t\t\t\tresult = this._getTransformedByDetachOperation(operation);\n\t\t\t\tbreak;\n\t\t\tdefault: result = ModelPosition._createAt(this);\n\t\t}\n\t\treturn result;\n\t}\n\t/**\n\t* Returns a copy of this position transformed by a detach operation.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedByDetachOperation(operation) {\n\t\treturn this._getTransformedByDeletion(operation.sourcePosition, operation.howMany) || ModelPosition._createAt(operation.sourcePosition);\n\t}\n\t/**\n\t* Returns a copy of this position transformed by an insert operation.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedByInsertOperation(operation) {\n\t\treturn this._getTransformedByInsertion(operation.position, operation.howMany);\n\t}\n\t/**\n\t* Returns a copy of this position transformed by a move operation.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedByMoveOperation(operation) {\n\t\treturn this._getTransformedByMove(operation.sourcePosition, operation.targetPosition, operation.howMany);\n\t}\n\t/**\n\t* Returns a copy of this position transformed by a split operation.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedBySplitOperation(operation) {\n\t\tconst movedRange = operation.movedRange;\n\t\tif (movedRange.containsPosition(this) || movedRange.start.isEqual(this) && this.stickiness == \"toNext\") return this._getCombined(operation.splitPosition, operation.moveTargetPosition);\n\t\telse if (operation.graveyardPosition) return this._getTransformedByMove(operation.graveyardPosition, operation.insertionPosition, 1);\n\t\telse return this._getTransformedByInsertion(operation.insertionPosition, 1);\n\t}\n\t/**\n\t* Returns a copy of this position transformed by merge operation.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedByMergeOperation(operation) {\n\t\tconst movedRange = operation.movedRange;\n\t\tconst isContained = movedRange.containsPosition(this) || movedRange.start.isEqual(this);\n\t\tlet pos;\n\t\tif (isContained) {\n\t\t\tpos = this._getCombined(operation.sourcePosition, operation.targetPosition);\n\t\t\tif (operation.sourcePosition.isBefore(operation.targetPosition)) pos = pos._getTransformedByDeletion(operation.deletionPosition, 1);\n\t\t} else if (this.isEqual(operation.deletionPosition)) pos = ModelPosition._createAt(operation.deletionPosition);\n\t\telse pos = this._getTransformedByMove(operation.deletionPosition, operation.graveyardPosition, 1);\n\t\treturn pos;\n\t}\n\t/**\n\t* Returns a copy of this position that is updated by removing `howMany` nodes starting from `deletePosition`.\n\t* It may happen that this position is in a removed node. If that is the case, `null` is returned instead.\n\t*\n\t* @internal\n\t* @param deletePosition Position before the first removed node.\n\t* @param howMany How many nodes are removed.\n\t* @returns Transformed position or `null`.\n\t*/\n\t_getTransformedByDeletion(deletePosition, howMany) {\n\t\tconst transformed = ModelPosition._createAt(this);\n\t\tif (this.root != deletePosition.root) return transformed;\n\t\tif (compareArrays(deletePosition.getParentPath(), this.getParentPath()) == \"same\") {\n\t\t\tif (deletePosition.offset < this.offset) if (deletePosition.offset + howMany > this.offset) return null;\n\t\t\telse transformed.offset -= howMany;\n\t\t} else if (compareArrays(deletePosition.getParentPath(), this.getParentPath()) == \"prefix\") {\n\t\t\tconst i = deletePosition.path.length - 1;\n\t\t\tif (deletePosition.offset <= this.path[i]) if (deletePosition.offset + howMany > this.path[i]) return null;\n\t\t\telse transformed.path[i] -= howMany;\n\t\t}\n\t\treturn transformed;\n\t}\n\t/**\n\t* Returns a copy of this position that is updated by inserting `howMany` nodes at `insertPosition`.\n\t*\n\t* @internal\n\t* @param insertPosition Position where nodes are inserted.\n\t* @param howMany How many nodes are inserted.\n\t* @returns Transformed position.\n\t*/\n\t_getTransformedByInsertion(insertPosition, howMany) {\n\t\tconst transformed = ModelPosition._createAt(this);\n\t\tif (this.root != insertPosition.root) return transformed;\n\t\tif (compareArrays(insertPosition.getParentPath(), this.getParentPath()) == \"same\") {\n\t\t\tif (insertPosition.offset < this.offset || insertPosition.offset == this.offset && this.stickiness != \"toPrevious\") transformed.offset += howMany;\n\t\t} else if (compareArrays(insertPosition.getParentPath(), this.getParentPath()) == \"prefix\") {\n\t\t\tconst i = insertPosition.path.length - 1;\n\t\t\tif (insertPosition.offset <= this.path[i]) transformed.path[i] += howMany;\n\t\t}\n\t\treturn transformed;\n\t}\n\t/**\n\t* Returns a copy of this position that is updated by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t*\n\t* @internal\n\t* @param sourcePosition Position before the first element to move.\n\t* @param targetPosition Position where moved elements will be inserted.\n\t* @param howMany How many consecutive nodes to move, starting from `sourcePosition`.\n\t* @returns Transformed position.\n\t*/\n\t_getTransformedByMove(sourcePosition, targetPosition, howMany) {\n\t\ttargetPosition = targetPosition._getTransformedByDeletion(sourcePosition, howMany);\n\t\tif (sourcePosition.isEqual(targetPosition)) return ModelPosition._createAt(this);\n\t\tconst transformed = this._getTransformedByDeletion(sourcePosition, howMany);\n\t\tif (transformed === null || sourcePosition.isEqual(this) && this.stickiness == \"toNext\" || sourcePosition.getShiftedBy(howMany).isEqual(this) && this.stickiness == \"toPrevious\") return this._getCombined(sourcePosition, targetPosition);\n\t\telse return transformed._getTransformedByInsertion(targetPosition, howMany);\n\t}\n\t/**\n\t* Returns a new position that is a combination of this position and given positions.\n\t*\n\t* The combined position is a copy of this position transformed by moving a range starting at `source` position\n\t* to the `target` position. It is expected that this position is inside the moved range.\n\t*\n\t* Example:\n\t*\n\t* ```ts\n\t* let original = model.createPositionFromPath( root, [ 2, 3, 1 ] );\n\t* let source = model.createPositionFromPath( root, [ 2, 2 ] );\n\t* let target = model.createPositionFromPath( otherRoot, [ 1, 1, 3 ] );\n\t* original._getCombined( source, target ); // path is [ 1, 1, 4, 1 ], root is `otherRoot`\n\t* ```\n\t*\n\t* Explanation:\n\t*\n\t* We have a position `[ 2, 3, 1 ]` and move some nodes from `[ 2, 2 ]` to `[ 1, 1, 3 ]`. The original position\n\t* was inside moved nodes and now should point to the new place. The moved nodes will be after\n\t* positions `[ 1, 1, 3 ]`, `[ 1, 1, 4 ]`, `[ 1, 1, 5 ]`. Since our position was in the second moved node,\n\t* the transformed position will be in a sub-tree of a node at `[ 1, 1, 4 ]`. Looking at original path, we\n\t* took care of `[ 2, 3 ]` part of it. Now we have to add the rest of the original path to the transformed path.\n\t* Finally, the transformed position will point to `[ 1, 1, 4, 1 ]`.\n\t*\n\t* @internal\n\t* @param source Beginning of the moved range.\n\t* @param target Position where the range is moved.\n\t* @returns Combined position.\n\t*/\n\t_getCombined(source, target) {\n\t\tconst i = source.path.length - 1;\n\t\tconst combined = ModelPosition._createAt(target);\n\t\tcombined.stickiness = this.stickiness;\n\t\tcombined.offset = combined.offset + this.path[i] - source.offset;\n\t\tcombined.path = [...combined.path, ...this.path.slice(i + 1)];\n\t\treturn combined;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\treturn {\n\t\t\troot: this.root.toJSON(),\n\t\t\tpath: Array.from(this.path),\n\t\t\tstickiness: this.stickiness\n\t\t};\n\t}\n\t/**\n\t* Returns a new position that is equal to current position.\n\t*/\n\tclone() {\n\t\treturn new this.constructor(this.root, this.path, this.stickiness);\n\t}\n\t/**\n\t* Creates position at the given location. The location can be specified as:\n\t*\n\t* * a {@link module:engine/model/position~ModelPosition position},\n\t* * parent element and offset (offset defaults to `0`),\n\t* * parent element and `'end'` (sets position at the end of that element),\n\t* * {@link module:engine/model/item~ModelItem model item} and `'before'` or `'after'` (sets position before or after given model item).\n\t*\n\t* This method is a shortcut to other factory methods such as:\n\t*\n\t* * {@link module:engine/model/position~ModelPosition._createBefore},\n\t* * {@link module:engine/model/position~ModelPosition._createAfter}.\n\t*\n\t* @internal\n\t* @param offset Offset or one of the flags. Used only when the first parameter\n\t* is a {@link module:engine/model/item~ModelItem model item}.\n\t* @param stickiness Position stickiness. Used only when the first parameter is a {@link module:engine/model/item~ModelItem model item}.\n\t*/\n\tstatic _createAt(itemOrPosition, offset, stickiness = \"toNone\") {\n\t\tif (itemOrPosition.is(\"model:position\")) return new ModelPosition(itemOrPosition.root, itemOrPosition.path, itemOrPosition.stickiness);\n\t\telse {\n\t\t\tconst node = itemOrPosition;\n\t\t\tif (offset == \"end\") offset = node.maxOffset;\n\t\t\telse if (offset == \"before\") return this._createBefore(node, stickiness);\n\t\t\telse if (offset == \"after\") return this._createAfter(node, stickiness);\n\t\t\telse if (offset !== 0 && !offset)\n /**\n\t\t\t* {@link module:engine/model/model~Model#createPositionAt `Model#createPositionAt()`}\n\t\t\t* requires the offset to be specified when the first parameter is a model item.\n\t\t\t*\n\t\t\t* @error model-createpositionat-offset-required\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"model-createpositionat-offset-required\", [this, itemOrPosition]);\n\t\t\tif (!node.is(\"element\") && !node.is(\"documentFragment\"))\n /**\n\t\t\t* Position parent have to be a model element or model document fragment.\n\t\t\t*\n\t\t\t* @error model-position-parent-incorrect\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"model-position-parent-incorrect\", [this, itemOrPosition]);\n\t\t\tconst path = node.getPath();\n\t\t\tpath.push(offset);\n\t\t\treturn new this(node.root, path, stickiness);\n\t\t}\n\t}\n\t/**\n\t* Creates a new position, after given {@link module:engine/model/item~ModelItem model item}.\n\t*\n\t* @internal\n\t* @param item Item after which the position should be placed.\n\t* @param stickiness Position stickiness.\n\t*/\n\tstatic _createAfter(item, stickiness) {\n\t\tif (!item.parent)\n /**\n\t\t* You cannot make a position after a root element.\n\t\t*\n\t\t* @error model-position-after-root\n\t\t* @param {module:engine/model/rootelement~ModelRootElement} root The root element..\n\t\t*/\n\t\tthrow new CKEditorError(\"model-position-after-root\", [this, item], { root: item });\n\t\treturn this._createAt(item.parent, item.endOffset, stickiness);\n\t}\n\t/**\n\t* Creates a new position, before the given {@link module:engine/model/item~ModelItem model item}.\n\t*\n\t* @internal\n\t* @param item Item before which the position should be placed.\n\t* @param stickiness Position stickiness.\n\t*/\n\tstatic _createBefore(item, stickiness) {\n\t\tif (!item.parent)\n /**\n\t\t* You cannot make a position before a root element.\n\t\t*\n\t\t* @error model-position-before-root\n\t\t* @param {module:engine/model/rootelement~ModelRootElement} root The root element..\n\t\t*/\n\t\tthrow new CKEditorError(\"model-position-before-root\", item, { root: item });\n\t\treturn this._createAt(item.parent, item.startOffset, stickiness);\n\t}\n\t/**\n\t* Creates a `Position` instance from given plain object (i.e. parsed JSON string).\n\t*\n\t* @param json Plain object to be converted to `Position`.\n\t* @param doc Document object that will be position owner.\n\t* @returns `Position` instance created using given plain object.\n\t*/\n\tstatic fromJSON(json, doc) {\n\t\tif (json.root === \"$graveyard\") {\n\t\t\tconst pos = new ModelPosition(doc.graveyard, json.path);\n\t\t\tpos.stickiness = json.stickiness;\n\t\t\treturn pos;\n\t\t}\n\t\tif (!doc.getRoot(json.root))\n /**\n\t\t* Cannot create position for document. Root with specified name does not exist.\n\t\t*\n\t\t* @error model-position-fromjson-no-root\n\t\t* @param {string} rootName The root name.\n\t\t*/\n\t\tthrow new CKEditorError(\"model-position-fromjson-no-root\", doc, { rootName: json.root });\n\t\treturn new ModelPosition(doc.getRoot(json.root), json.path, json.stickiness);\n\t}\n};\nModelPosition.prototype.is = function(type) {\n\treturn type === \"position\" || type === \"model:position\";\n};\n/**\n* Returns a text node at the given position.\n*\n* This is a helper function optimized to reuse the position parent instance for performance reasons.\n*\n* Normally, you should use {@link module:engine/model/position~ModelPosition#textNode `Position#textNode`}.\n* If you start hitting performance issues with {@link module:engine/model/position~ModelPosition#parent `Position#parent`}\n* check if your algorithm does not access it multiple times (which can happen directly or indirectly via other position properties).\n*\n* See https://github.com/ckeditor/ckeditor5/issues/6579.\n*\n* See also:\n*\n* * {@link module:engine/model/position~getNodeAfterPosition}\n* * {@link module:engine/model/position~getNodeBeforePosition}\n*\n* @param position\n* @param positionParent The parent of the given position.\n* @internal\n*/\nfunction getTextNodeAtPosition(position, positionParent) {\n\tconst node = positionParent.getChildAtOffset(position.offset);\n\tif (node && node.is(\"$text\") && node.startOffset < position.offset) return node;\n\treturn null;\n}\n/**\n* Returns the node after the given position.\n*\n* This is a helper function optimized to reuse the position parent instance and the calculation of the text node at the\n* specific position for performance reasons.\n*\n* Normally, you should use {@link module:engine/model/position~ModelPosition#nodeAfter `Position#nodeAfter`}.\n* If you start hitting performance issues with {@link module:engine/model/position~ModelPosition#parent `Position#parent`} and/or\n* {@link module:engine/model/position~ModelPosition#textNode `Position#textNode`}\n* check if your algorithm does not access those properties multiple times\n* (which can happen directly or indirectly via other position properties).\n*\n* See https://github.com/ckeditor/ckeditor5/issues/6579 and https://github.com/ckeditor/ckeditor5/issues/6582.\n*\n* See also:\n*\n* * {@link module:engine/model/position~getTextNodeAtPosition}\n* * {@link module:engine/model/position~getNodeBeforePosition}\n*\n* @param position Position to check.\n* @param positionParent The parent of the given position.\n* @param textNode Text node at the given position.\n* @internal\n*/\nfunction getNodeAfterPosition(position, positionParent, textNode) {\n\tif (textNode !== null) return null;\n\treturn positionParent.getChildAtOffset(position.offset);\n}\n/**\n* Returns the node before the given position.\n*\n* Refer to {@link module:engine/model/position~getNodeBeforePosition} for documentation on when to use this util method.\n*\n* See also:\n*\n* * {@link module:engine/model/position~getTextNodeAtPosition}\n* * {@link module:engine/model/position~getNodeAfterPosition}\n*\n* @param position Position to check.\n* @param positionParent The parent of the given position.\n* @param textNode Text node at the given position.\n* @internal\n*/\nfunction getNodeBeforePosition(position, positionParent, textNode) {\n\tif (textNode !== null) return null;\n\treturn positionParent.getChild(positionParent.offsetToIndex(position.offset) - 1);\n}\n/**\n* This is a helper function for `Position#isTouching()`.\n*\n* It checks whether to given positions are touching, considering that they have the same root and paths\n* until given level, and at given level they differ by 1 (so they are branching at `level` point).\n*\n* The exact requirements for touching positions are described in `Position#isTouching()` and also\n* in the body of this function.\n*\n* @param left Position \"on the left\" (it is before `right`).\n* @param right Position \"on the right\" (it is after `left`).\n* @param level Level on which the positions are different.\n*/\nfunction checkTouchingBranch(left, right, level) {\n\tif (level + 1 === left.path.length) return false;\n\tif (!checkOnlyZeroes(right.path, level + 1)) return false;\n\tif (!checkOnlyMaxOffset(left, level + 1)) return false;\n\treturn true;\n}\n/**\n* Checks whether for given array, starting from given index until the end of the array, all items are `0`s.\n*\n* This is a helper function for `Position#isTouching()`.\n*/\nfunction checkOnlyZeroes(arr, idx) {\n\twhile (idx < arr.length) {\n\t\tif (arr[idx] !== 0) return false;\n\t\tidx++;\n\t}\n\treturn true;\n}\n/**\n* Checks whether for given position, starting from given path level, whether the position is at the end of\n* its parent and whether each element on the path to the position is also at at the end of its parent.\n*\n* This is a helper function for `Position#isTouching()`.\n*/\nfunction checkOnlyMaxOffset(pos, level) {\n\tlet parent = pos.parent;\n\tlet idx = pos.path.length - 1;\n\tlet add = 0;\n\twhile (idx >= level) {\n\t\tif (pos.path[idx] + add !== parent.maxOffset) return false;\n\t\tadd = 1;\n\t\tidx--;\n\t\tparent = parent.parent;\n\t}\n\treturn true;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/range\n*/\n/**\n* Represents a range in the model tree.\n*\n* A range is defined by its {@link module:engine/model/range~ModelRange#start} and {@link module:engine/model/range~ModelRange#end}\n* positions.\n*\n* You can create range instances via its constructor or the `createRange*()` factory methods of\n* {@link module:engine/model/model~Model} and {@link module:engine/model/writer~ModelWriter}.\n*/\nvar ModelRange = class ModelRange extends ModelTypeCheckable {\n\t/**\n\t* Start position.\n\t*/\n\tstart;\n\t/**\n\t* End position.\n\t*/\n\tend;\n\t/**\n\t* Creates a range spanning from `start` position to `end` position.\n\t*\n\t* @param start The start position.\n\t* @param end The end position. If not set, the range will be collapsed at the `start` position.\n\t*/\n\tconstructor(start, end) {\n\t\tsuper();\n\t\tthis.start = ModelPosition._createAt(start);\n\t\tthis.end = end ? ModelPosition._createAt(end) : ModelPosition._createAt(start);\n\t\tthis.start.stickiness = this.isCollapsed ? \"toNone\" : \"toNext\";\n\t\tthis.end.stickiness = this.isCollapsed ? \"toNone\" : \"toPrevious\";\n\t}\n\t/**\n\t* Iterable interface.\n\t*\n\t* Iterates over all {@link module:engine/model/item~ModelItem items} that are in this range and returns\n\t* them together with additional information like length or {@link module:engine/model/position~ModelPosition positions},\n\t* grouped as {@link module:engine/model/treewalker~ModelTreeWalkerValue}.\n\t* It iterates over all {@link module:engine/model/textproxy~ModelTextProxy text contents} that are inside the range\n\t* and all the {@link module:engine/model/element~ModelElement}s that are entered into when iterating over this range.\n\t*\n\t* This iterator uses {@link module:engine/model/treewalker~ModelTreeWalker} with `boundaries` set to this range\n\t* and `ignoreElementEnd` option set to `true`.\n\t*/\n\t*[Symbol.iterator]() {\n\t\tyield* new ModelTreeWalker({\n\t\t\tboundaries: this,\n\t\t\tignoreElementEnd: true\n\t\t});\n\t}\n\t/**\n\t* Describes whether the range is collapsed, that is if {@link #start} and\n\t* {@link #end} positions are equal.\n\t*/\n\tget isCollapsed() {\n\t\treturn this.start.isEqual(this.end);\n\t}\n\t/**\n\t* Describes whether this range is flat, that is if {@link #start} position and\n\t* {@link #end} position are in the same {@link module:engine/model/position~ModelPosition#parent}.\n\t*/\n\tget isFlat() {\n\t\tconst startParentPath = this.start.getParentPath();\n\t\tconst endParentPath = this.end.getParentPath();\n\t\treturn compareArrays(startParentPath, endParentPath) == \"same\";\n\t}\n\t/**\n\t* Range root element.\n\t*/\n\tget root() {\n\t\treturn this.start.root;\n\t}\n\t/**\n\t* Checks whether this range contains given {@link module:engine/model/position~ModelPosition position}.\n\t*\n\t* @param position Position to check.\n\t* @returns `true` if given {@link module:engine/model/position~ModelPosition position} is contained\n\t* in this range,`false` otherwise.\n\t*/\n\tcontainsPosition(position) {\n\t\treturn position.isAfter(this.start) && position.isBefore(this.end);\n\t}\n\t/**\n\t* Checks whether this range contains given {@link module:engine/model/range~ModelRange range}.\n\t*\n\t* @param otherRange Range to check.\n\t* @param loose Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n\t* start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n\t* even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n\t* @returns {Boolean} `true` if given {@link module:engine/model/range~ModelRange range} boundaries are contained by this range,\n\t* `false` otherwise.\n\t*/\n\tcontainsRange(otherRange, loose = false) {\n\t\tif (otherRange.isCollapsed) loose = false;\n\t\tconst containsStart = this.containsPosition(otherRange.start) || loose && this.start.isEqual(otherRange.start);\n\t\tconst containsEnd = this.containsPosition(otherRange.end) || loose && this.end.isEqual(otherRange.end);\n\t\treturn containsStart && containsEnd;\n\t}\n\t/**\n\t* Checks whether given {@link module:engine/model/item~ModelItem} is inside this range.\n\t*/\n\tcontainsItem(item) {\n\t\tconst pos = ModelPosition._createBefore(item);\n\t\treturn this.containsPosition(pos) || this.start.isEqual(pos);\n\t}\n\t/**\n\t* Two ranges are equal if their {@link #start} and {@link #end} positions are equal.\n\t*\n\t* @param otherRange Range to compare with.\n\t* @returns `true` if ranges are equal, `false` otherwise.\n\t*/\n\tisEqual(otherRange) {\n\t\treturn this.start.isEqual(otherRange.start) && this.end.isEqual(otherRange.end);\n\t}\n\t/**\n\t* Checks and returns whether this range intersects with given range.\n\t*\n\t* @param otherRange Range to compare with.\n\t* @returns `true` if ranges intersect, `false` otherwise.\n\t*/\n\tisIntersecting(otherRange) {\n\t\treturn this.start.isBefore(otherRange.end) && this.end.isAfter(otherRange.start);\n\t}\n\t/**\n\t* Computes which part(s) of this {@link module:engine/model/range~ModelRange range} is not a part of given\n\t* {@link module:engine/model/range~ModelRange range}.\n\t* Returned array contains zero, one or two {@link module:engine/model/range~ModelRange ranges}.\n\t*\n\t* Examples:\n\t*\n\t* ```ts\n\t* let range = model.createRange(\n\t* \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t* \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t* );\n\t* let otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 5 ] ) );\n\t* let transformed = range.getDifference( otherRange );\n\t* // transformed array has no ranges because `otherRange` contains `range`\n\t*\n\t* otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 3 ] ) );\n\t* transformed = range.getDifference( otherRange );\n\t* // transformed array has one range: from [ 3 ] to [ 4, 0, 1 ]\n\t*\n\t* otherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 4 ] ) );\n\t* transformed = range.getDifference( otherRange );\n\t* // transformed array has two ranges: from [ 2, 7 ] to [ 3 ] and from [ 4 ] to [ 4, 0, 1 ]\n\t* ```\n\t*\n\t* @param otherRange Range to differentiate against.\n\t* @returns The difference between ranges.\n\t*/\n\tgetDifference(otherRange) {\n\t\tconst ranges = [];\n\t\tif (this.isIntersecting(otherRange)) {\n\t\t\tif (this.containsPosition(otherRange.start)) ranges.push(new ModelRange(this.start, otherRange.start));\n\t\t\tif (this.containsPosition(otherRange.end)) ranges.push(new ModelRange(otherRange.end, this.end));\n\t\t} else ranges.push(new ModelRange(this.start, this.end));\n\t\treturn ranges;\n\t}\n\t/**\n\t* Returns an intersection of this {@link module:engine/model/range~ModelRange range} and given\n\t* {@link module:engine/model/range~ModelRange range}.\n\t* Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n\t*\n\t* Examples:\n\t*\n\t* ```ts\n\t* let range = model.createRange(\n\t* \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t* \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t* );\n\t* let otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 2 ] ) );\n\t* let transformed = range.getIntersection( otherRange ); // null - ranges have no common part\n\t*\n\t* otherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 5 ] ) );\n\t* transformed = range.getIntersection( otherRange ); // range from [ 3 ] to [ 4, 0, 1 ]\n\t* ```\n\t*\n\t* @param otherRange Range to check for intersection.\n\t* @returns A common part of given ranges or `null` if ranges have no common part.\n\t*/\n\tgetIntersection(otherRange) {\n\t\tif (this.isIntersecting(otherRange)) {\n\t\t\tlet commonRangeStart = this.start;\n\t\t\tlet commonRangeEnd = this.end;\n\t\t\tif (this.containsPosition(otherRange.start)) commonRangeStart = otherRange.start;\n\t\t\tif (this.containsPosition(otherRange.end)) commonRangeEnd = otherRange.end;\n\t\t\treturn new ModelRange(commonRangeStart, commonRangeEnd);\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Returns a range created by joining this {@link module:engine/model/range~ModelRange range} with the given\n\t* {@link module:engine/model/range~ModelRange range}.\n\t* If ranges have no common part, returns `null`.\n\t*\n\t* Examples:\n\t*\n\t* ```ts\n\t* let range = model.createRange(\n\t* \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t* \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t* );\n\t* let otherRange = model.createRange(\n\t* \tmodel.createPositionFromPath( root, [ 1 ] ),\n\t* \tmodel.createPositionFromPath( root, [ 2 ] )\n\t* );\n\t* let transformed = range.getJoined( otherRange ); // null - ranges have no common part\n\t*\n\t* otherRange = model.createRange(\n\t* \tmodel.createPositionFromPath( root, [ 3 ] ),\n\t* \tmodel.createPositionFromPath( root, [ 5 ] )\n\t* );\n\t* transformed = range.getJoined( otherRange ); // range from [ 2, 7 ] to [ 5 ]\n\t* ```\n\t*\n\t* @param otherRange Range to be joined.\n\t* @param loose Whether the intersection check is loose or strict. If the check is strict (`false`),\n\t* ranges are tested for intersection or whether start/end positions are equal. If the check is loose (`true`),\n\t* compared range is also checked if it's {@link module:engine/model/position~ModelPosition#isTouching touching} current range.\n\t* @returns A sum of given ranges or `null` if ranges have no common part.\n\t*/\n\tgetJoined(otherRange, loose = false) {\n\t\tlet shouldJoin = this.isIntersecting(otherRange);\n\t\tif (!shouldJoin) if (this.start.isBefore(otherRange.start)) shouldJoin = loose ? this.end.isTouching(otherRange.start) : this.end.isEqual(otherRange.start);\n\t\telse shouldJoin = loose ? otherRange.end.isTouching(this.start) : otherRange.end.isEqual(this.start);\n\t\tif (!shouldJoin) return null;\n\t\tlet startPosition = this.start;\n\t\tlet endPosition = this.end;\n\t\tif (otherRange.start.isBefore(startPosition)) startPosition = otherRange.start;\n\t\tif (otherRange.end.isAfter(endPosition)) endPosition = otherRange.end;\n\t\treturn new ModelRange(startPosition, endPosition);\n\t}\n\t/**\n\t* Computes and returns the smallest set of {@link #isFlat flat} ranges, that covers this range in whole.\n\t*\n\t* See an example of a model structure (`[` and `]` are range boundaries):\n\t*\n\t* ```\n\t* root root\n\t* |- element DIV DIV P2 P3 DIV\n\t* | |- element H H P1 f o o b a r H P4\n\t* | | |- \"fir[st\" fir[st lorem se]cond ipsum\n\t* | |- element P1\n\t* | | |- \"lorem\" ||\n\t* |- element P2 ||\n\t* | |- \"foo\" VV\n\t* |- element P3\n\t* | |- \"bar\" root\n\t* |- element DIV DIV [P2 P3] DIV\n\t* | |- element H H [P1] f o o b a r H P4\n\t* | | |- \"se]cond\" fir[st] lorem [se]cond ipsum\n\t* | |- element P4\n\t* | | |- \"ipsum\"\n\t* ```\n\t*\n\t* As it can be seen, letters contained in the range are: `stloremfoobarse`, spread across different parents.\n\t* We are looking for minimal set of flat ranges that contains the same nodes.\n\t*\n\t* Minimal flat ranges for above range `( [ 0, 0, 3 ], [ 3, 0, 2 ] )` will be:\n\t*\n\t* ```\n\t* ( [ 0, 0, 3 ], [ 0, 0, 5 ] ) = \"st\"\n\t* ( [ 0, 1 ], [ 0, 2 ] ) = element P1 (\"lorem\")\n\t* ( [ 1 ], [ 3 ] ) = element P2, element P3 (\"foobar\")\n\t* ( [ 3, 0, 0 ], [ 3, 0, 2 ] ) = \"se\"\n\t* ```\n\t*\n\t* **Note:** if an {@link module:engine/model/element~ModelElement element} is not wholly contained in this range, it won't be returned\n\t* in any of the returned flat ranges. See in the example how `H` elements at the beginning and at the end of the range\n\t* were omitted. Only their parts that were wholly in the range were returned.\n\t*\n\t* **Note:** this method is not returning flat ranges that contain no nodes.\n\t*\n\t* @returns Array of flat ranges covering this range.\n\t*/\n\tgetMinimalFlatRanges() {\n\t\tconst ranges = [];\n\t\tconst diffAt = this.start.getCommonPath(this.end).length;\n\t\tconst pos = ModelPosition._createAt(this.start);\n\t\tlet posParent = pos.parent;\n\t\twhile (pos.path.length > diffAt + 1) {\n\t\t\tconst howMany = posParent.maxOffset - pos.offset;\n\t\t\tif (howMany !== 0) ranges.push(new ModelRange(pos, pos.getShiftedBy(howMany)));\n\t\t\tpos.path = pos.path.slice(0, -1);\n\t\t\tpos.offset++;\n\t\t\tposParent = posParent.parent;\n\t\t}\n\t\twhile (pos.path.length <= this.end.path.length) {\n\t\t\tconst offset = this.end.path[pos.path.length - 1];\n\t\t\tconst howMany = offset - pos.offset;\n\t\t\tif (howMany !== 0) ranges.push(new ModelRange(pos, pos.getShiftedBy(howMany)));\n\t\t\tpos.offset = offset;\n\t\t\tpos.path.push(0);\n\t\t}\n\t\treturn ranges;\n\t}\n\t/**\n\t* Creates a {@link module:engine/model/treewalker~ModelTreeWalker TreeWalker} instance with this range as a boundary.\n\t*\n\t* For example, to iterate over all items in the entire document root:\n\t*\n\t* ```ts\n\t* // Create a range spanning over the entire root content:\n\t* const range = editor.model.createRangeIn( editor.model.document.getRoot() );\n\t*\n\t* // Iterate over all items in this range:\n\t* for ( const value of range.getWalker() ) {\n\t* \tconsole.log( value.item );\n\t* }\n\t* ```\n\t*\n\t* @param options Object with configuration options. See {@link module:engine/model/treewalker~ModelTreeWalker}.\n\t*/\n\tgetWalker(options = {}) {\n\t\toptions.boundaries = this;\n\t\treturn new ModelTreeWalker(options);\n\t}\n\t/**\n\t* Returns an iterator that iterates over all {@link module:engine/model/item~ModelItem items} that are in this range and returns\n\t* them.\n\t*\n\t* This method uses {@link module:engine/model/treewalker~ModelTreeWalker} with `boundaries` set to this range and\n\t* `ignoreElementEnd` option set to `true`. However it returns only {@link module:engine/model/item~ModelItem model items},\n\t* not {@link module:engine/model/treewalker~ModelTreeWalkerValue}.\n\t*\n\t* You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~ModelTreeWalker} for\n\t* a full list of available options.\n\t*\n\t* @param options Object with configuration options. See {@link module:engine/model/treewalker~ModelTreeWalker}.\n\t*/\n\t*getItems(options = {}) {\n\t\toptions.boundaries = this;\n\t\toptions.ignoreElementEnd = true;\n\t\tconst treeWalker = new ModelTreeWalker(options);\n\t\tfor (const value of treeWalker) yield value.item;\n\t}\n\t/**\n\t* Returns an iterator that iterates over all {@link module:engine/model/position~ModelPosition positions} that are boundaries or\n\t* contained in this range.\n\t*\n\t* This method uses {@link module:engine/model/treewalker~ModelTreeWalker} with `boundaries` set to this range. However it returns only\n\t* {@link module:engine/model/position~ModelPosition positions}, not {@link module:engine/model/treewalker~ModelTreeWalkerValue}.\n\t*\n\t* You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~ModelTreeWalker} for\n\t* a full list of available options.\n\t*\n\t* @param options Object with configuration options. See {@link module:engine/model/treewalker~ModelTreeWalker}.\n\t*/\n\t*getPositions(options = {}) {\n\t\toptions.boundaries = this;\n\t\tconst treeWalker = new ModelTreeWalker(options);\n\t\tyield treeWalker.position;\n\t\tfor (const value of treeWalker) yield value.nextPosition;\n\t}\n\t/**\n\t* Returns a range that is a result of transforming this range by given `operation`.\n\t*\n\t* **Note:** transformation may break one range into multiple ranges (for example, when a part of the range is\n\t* moved to a different part of document tree). For this reason, an array is returned by this method and it\n\t* may contain one or more `Range` instances.\n\t*\n\t* @param operation Operation to transform range by.\n\t* @returns Range which is the result of transformation.\n\t*/\n\tgetTransformedByOperation(operation) {\n\t\tswitch (operation.type) {\n\t\t\tcase \"insert\": return this._getTransformedByInsertOperation(operation);\n\t\t\tcase \"move\":\n\t\t\tcase \"remove\":\n\t\t\tcase \"reinsert\": return this._getTransformedByMoveOperation(operation);\n\t\t\tcase \"split\": return [this._getTransformedBySplitOperation(operation)];\n\t\t\tcase \"merge\": return [this._getTransformedByMergeOperation(operation)];\n\t\t\tcase \"detach\": return this._getTransformedByDetachOperation(operation);\n\t\t}\n\t\treturn [new ModelRange(this.start, this.end)];\n\t}\n\t/**\n\t* Returns a range that is a result of transforming this range by multiple `operations`.\n\t*\n\t* @see module:engine/model/range~ModelRange#getTransformedByOperation\n\t* @param operations Operations to transform the range by.\n\t* @returns Range which is the result of transformation.\n\t*/\n\tgetTransformedByOperations(operations) {\n\t\tconst ranges = [new ModelRange(this.start, this.end)];\n\t\tfor (const operation of operations) for (let i = 0; i < ranges.length; i++) {\n\t\t\tconst result = ranges[i].getTransformedByOperation(operation);\n\t\t\tranges.splice(i, 1, ...result);\n\t\t\ti += result.length - 1;\n\t\t}\n\t\tfor (let i = 0; i < ranges.length; i++) {\n\t\t\tconst range = ranges[i];\n\t\t\tfor (let j = i + 1; j < ranges.length; j++) {\n\t\t\t\tconst next = ranges[j];\n\t\t\t\tif (range.containsRange(next) || next.containsRange(range) || range.isEqual(next)) ranges.splice(j, 1);\n\t\t\t}\n\t\t}\n\t\treturn ranges;\n\t}\n\t/**\n\t* Returns an {@link module:engine/model/element~ModelElement} or {@link module:engine/model/documentfragment~ModelDocumentFragment}\n\t* which is a common ancestor of the range's both ends (in which the entire range is contained).\n\t*/\n\tgetCommonAncestor() {\n\t\treturn this.start.getCommonAncestor(this.end);\n\t}\n\t/**\n\t* Returns an {@link module:engine/model/element~ModelElement Element} contained by the range.\n\t* The element will be returned when it is the **only** node within the range and **fully–contained**\n\t* at the same time.\n\t*/\n\tgetContainedElement() {\n\t\tif (this.isCollapsed) return null;\n\t\tconst nodeAfterStart = this.start.nodeAfter;\n\t\tconst nodeBeforeEnd = this.end.nodeBefore;\n\t\tif (nodeAfterStart && nodeAfterStart.is(\"element\") && nodeAfterStart === nodeBeforeEnd) return nodeAfterStart;\n\t\treturn null;\n\t}\n\t/**\n\t* Converts `Range` to plain object and returns it.\n\t*\n\t* @returns `Range` converted to plain object.\n\t*/\n\ttoJSON() {\n\t\treturn {\n\t\t\tstart: this.start.toJSON(),\n\t\t\tend: this.end.toJSON()\n\t\t};\n\t}\n\t/**\n\t* Returns a new range that is equal to current range.\n\t*/\n\tclone() {\n\t\treturn new this.constructor(this.start, this.end);\n\t}\n\t/**\n\t* Returns a result of transforming a copy of this range by insert operation.\n\t*\n\t* One or more ranges may be returned as a result of this transformation.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedByInsertOperation(operation, spread = false) {\n\t\treturn this._getTransformedByInsertion(operation.position, operation.howMany, spread);\n\t}\n\t/**\n\t* Returns a result of transforming a copy of this range by move operation.\n\t*\n\t* One or more ranges may be returned as a result of this transformation.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedByMoveOperation(operation, spread = false) {\n\t\tconst sourcePosition = operation.sourcePosition;\n\t\tconst howMany = operation.howMany;\n\t\tconst targetPosition = operation.targetPosition;\n\t\treturn this._getTransformedByMove(sourcePosition, targetPosition, howMany, spread);\n\t}\n\t/**\n\t* Returns a result of transforming a copy of this range by split operation.\n\t*\n\t* Always one range is returned. The transformation is done in a way to not break the range.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedBySplitOperation(operation) {\n\t\tconst start = this.start._getTransformedBySplitOperation(operation);\n\t\tlet end = this.end._getTransformedBySplitOperation(operation);\n\t\tif (this.end.isEqual(operation.insertionPosition)) end = this.end.getShiftedBy(1);\n\t\tif (start.root != end.root) end = this.end.getShiftedBy(-1);\n\t\treturn new ModelRange(start, end);\n\t}\n\t/**\n\t* Returns a result of transforming a copy of this range by merge operation.\n\t*\n\t* Always one range is returned. The transformation is done in a way to not break the range.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedByMergeOperation(operation) {\n\t\tif (this.start.isEqual(operation.targetPosition) && this.end.isEqual(operation.deletionPosition)) return new ModelRange(this.start);\n\t\tlet start = this.start._getTransformedByMergeOperation(operation);\n\t\tlet end = this.end._getTransformedByMergeOperation(operation);\n\t\tif (start.root != end.root) end = this.end.getShiftedBy(-1);\n\t\tif (start.isAfter(end)) {\n\t\t\tif (operation.sourcePosition.isBefore(operation.targetPosition)) {\n\t\t\t\tstart = ModelPosition._createAt(end);\n\t\t\t\tstart.offset = 0;\n\t\t\t} else {\n\t\t\t\tif (!operation.deletionPosition.isEqual(start)) end = operation.deletionPosition;\n\t\t\t\tstart = operation.targetPosition;\n\t\t\t}\n\t\t\treturn new ModelRange(start, end);\n\t\t}\n\t\treturn new ModelRange(start, end);\n\t}\n\t/**\n\t* Returns a result of transforming a copy of this range by detach operation.\n\t*\n\t* If the range is completely removed, an empty array is returned.\n\t*\n\t* @internal\n\t*/\n\t_getTransformedByDetachOperation(operation) {\n\t\tconst result = this._getTransformedByDeletion(operation.sourcePosition, operation.howMany);\n\t\treturn result ? [result] : [];\n\t}\n\t/**\n\t* Returns an array containing one or two {@link module:engine/model/range~ModelRange ranges} that are a result of transforming this\n\t* {@link module:engine/model/range~ModelRange range} by inserting `howMany` nodes at `insertPosition`. Two\n\t* {@link module:engine/model/range~ModelRange ranges} are returned if the insertion was inside this\n\t* {@link module:engine/model/range~ModelRange range} and `spread` is set to `true`.\n\t*\n\t* Examples:\n\t*\n\t* ```ts\n\t* let range = model.createRange(\n\t* \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t* \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t* );\n\t* let transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 1 ] ), 2 );\n\t* // transformed array has one range from [ 4, 7 ] to [ 6, 0, 1 ]\n\t*\n\t* transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 4, 0, 0 ] ), 4 );\n\t* // transformed array has one range from [ 2, 7 ] to [ 4, 0, 5 ]\n\t*\n\t* transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 3, 2 ] ), 4 );\n\t* // transformed array has one range, which is equal to original range\n\t*\n\t* transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 3, 2 ] ), 4, true );\n\t* // transformed array has two ranges: from [ 2, 7 ] to [ 3, 2 ] and from [ 3, 6 ] to [ 4, 0, 1 ]\n\t* ```\n\t*\n\t* @internal\n\t* @param insertPosition Position where nodes are inserted.\n\t* @param howMany How many nodes are inserted.\n\t* @param spread Flag indicating whether this range should be spread if insertion\n\t* was inside the range. Defaults to `false`.\n\t* @returns Result of the transformation.\n\t*/\n\t_getTransformedByInsertion(insertPosition, howMany, spread = false) {\n\t\tif (spread && this.containsPosition(insertPosition)) return [new ModelRange(this.start, insertPosition), new ModelRange(insertPosition.getShiftedBy(howMany), this.end._getTransformedByInsertion(insertPosition, howMany))];\n\t\telse {\n\t\t\tconst range = new ModelRange(this.start, this.end);\n\t\t\trange.start = range.start._getTransformedByInsertion(insertPosition, howMany);\n\t\t\trange.end = range.end._getTransformedByInsertion(insertPosition, howMany);\n\t\t\treturn [range];\n\t\t}\n\t}\n\t/**\n\t* Returns an array containing {@link module:engine/model/range~ModelRange ranges} that are a result of transforming this\n\t* {@link module:engine/model/range~ModelRange range} by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t*\n\t* @internal\n\t* @param sourcePosition Position from which nodes are moved.\n\t* @param targetPosition Position to where nodes are moved.\n\t* @param howMany How many nodes are moved.\n\t* @param spread Whether the range should be spread if the move points inside the range.\n\t* @returns Result of the transformation.\n\t*/\n\t_getTransformedByMove(sourcePosition, targetPosition, howMany, spread = false) {\n\t\tif (this.isCollapsed) {\n\t\t\tconst newPos = this.start._getTransformedByMove(sourcePosition, targetPosition, howMany);\n\t\t\treturn [new ModelRange(newPos)];\n\t\t}\n\t\tconst moveRange = ModelRange._createFromPositionAndShift(sourcePosition, howMany);\n\t\tconst insertPosition = targetPosition._getTransformedByDeletion(sourcePosition, howMany);\n\t\tif (this.containsPosition(targetPosition) && !spread) {\n\t\t\tif (moveRange.containsPosition(this.start) || moveRange.containsPosition(this.end)) {\n\t\t\t\tconst start = this.start._getTransformedByMove(sourcePosition, targetPosition, howMany);\n\t\t\t\tconst end = this.end._getTransformedByMove(sourcePosition, targetPosition, howMany);\n\t\t\t\treturn [new ModelRange(start, end)];\n\t\t\t}\n\t\t}\n\t\tlet result;\n\t\tconst differenceSet = this.getDifference(moveRange);\n\t\tlet difference = null;\n\t\tconst common = this.getIntersection(moveRange);\n\t\tif (differenceSet.length == 1) difference = new ModelRange(differenceSet[0].start._getTransformedByDeletion(sourcePosition, howMany), differenceSet[0].end._getTransformedByDeletion(sourcePosition, howMany));\n\t\telse if (differenceSet.length == 2) difference = new ModelRange(this.start, this.end._getTransformedByDeletion(sourcePosition, howMany));\n\t\tif (difference) result = difference._getTransformedByInsertion(insertPosition, howMany, common !== null || spread);\n\t\telse result = [];\n\t\tif (common) {\n\t\t\tconst transformedCommon = new ModelRange(common.start._getCombined(moveRange.start, insertPosition), common.end._getCombined(moveRange.start, insertPosition));\n\t\t\tif (result.length == 2) result.splice(1, 0, transformedCommon);\n\t\t\telse result.push(transformedCommon);\n\t\t}\n\t\treturn result;\n\t}\n\t/**\n\t* Returns a copy of this range that is transformed by deletion of `howMany` nodes from `deletePosition`.\n\t*\n\t* If the deleted range is intersecting with the transformed range, the transformed range will be shrank.\n\t*\n\t* If the deleted range contains transformed range, `null` will be returned.\n\t*\n\t* @internal\n\t* @param deletePosition Position from which nodes are removed.\n\t* @param howMany How many nodes are removed.\n\t* @returns Result of the transformation.\n\t*/\n\t_getTransformedByDeletion(deletePosition, howMany) {\n\t\tlet newStart = this.start._getTransformedByDeletion(deletePosition, howMany);\n\t\tlet newEnd = this.end._getTransformedByDeletion(deletePosition, howMany);\n\t\tif (newStart == null && newEnd == null) return null;\n\t\tif (newStart == null) newStart = deletePosition;\n\t\tif (newEnd == null) newEnd = deletePosition;\n\t\treturn new ModelRange(newStart, newEnd);\n\t}\n\t/**\n\t* Creates a new range, spreading from specified {@link module:engine/model/position~ModelPosition position} to a position moved by\n\t* given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n\t*\n\t* @internal\n\t* @param position Beginning of the range.\n\t* @param shift How long the range should be.\n\t*/\n\tstatic _createFromPositionAndShift(position, shift) {\n\t\tconst start = position;\n\t\tconst end = position.getShiftedBy(shift);\n\t\treturn shift > 0 ? new this(start, end) : new this(end, start);\n\t}\n\t/**\n\t* Creates a range inside an {@link module:engine/model/element~ModelElement element} which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* @internal\n\t* @param element Element which is a parent for the range.\n\t*/\n\tstatic _createIn(element) {\n\t\treturn new this(ModelPosition._createAt(element, 0), ModelPosition._createAt(element, element.maxOffset));\n\t}\n\t/**\n\t* Creates a range that starts before given {@link module:engine/model/item~ModelItem model item} and ends after it.\n\t*\n\t* @internal\n\t*/\n\tstatic _createOn(item) {\n\t\treturn this._createFromPositionAndShift(ModelPosition._createBefore(item), item.offsetSize);\n\t}\n\t/**\n\t* Combines all ranges from the passed array into a one range. At least one range has to be passed.\n\t* Passed ranges must not have common parts.\n\t*\n\t* The first range from the array is a reference range. If other ranges start or end on the exactly same position where\n\t* the reference range, they get combined into one range.\n\t*\n\t* ```\n\t* [ ][] [ ][ ][ ][ ][] [ ] // Passed ranges, shown sorted\n\t* [ ] // The result of the function if the first range was a reference range.\n\t* [ ] // The result of the function if the third-to-seventh range was a reference range.\n\t* [ ] // The result of the function if the last range was a reference range.\n\t* ```\n\t*\n\t* @internal\n\t* @param ranges Ranges to combine.\n\t* @returns Combined range.\n\t*/\n\tstatic _createFromRanges(ranges) {\n\t\tif (ranges.length === 0)\n /**\n\t\t* At least one range has to be passed to\n\t\t* {@link module:engine/model/range~ModelRange._createFromRanges `Range._createFromRanges()`}.\n\t\t*\n\t\t* @error range-create-from-ranges-empty-array\n\t\t*/\n\t\tthrow new CKEditorError(\"range-create-from-ranges-empty-array\", null);\n\t\telse if (ranges.length == 1) return ranges[0].clone();\n\t\tconst ref = ranges[0];\n\t\tranges.sort((a, b) => {\n\t\t\treturn a.start.isAfter(b.start) ? 1 : -1;\n\t\t});\n\t\tconst refIndex = ranges.indexOf(ref);\n\t\tconst result = new this(ref.start, ref.end);\n\t\tfor (let i = refIndex - 1; i >= 0; i--) if (ranges[i].end.isEqual(result.start)) result.start = ModelPosition._createAt(ranges[i].start);\n\t\telse break;\n\t\tfor (let i = refIndex + 1; i < ranges.length; i++) if (ranges[i].start.isEqual(result.end)) result.end = ModelPosition._createAt(ranges[i].end);\n\t\telse break;\n\t\treturn result;\n\t}\n\t/**\n\t* Creates a `Range` instance from given plain object (i.e. parsed JSON string).\n\t*\n\t* @param json Plain object to be converted to `Range`.\n\t* @param doc Document object that will be range owner.\n\t* @returns `Range` instance created using given plain object.\n\t*/\n\tstatic fromJSON(json, doc) {\n\t\treturn new this(ModelPosition.fromJSON(json.start, doc), ModelPosition.fromJSON(json.end, doc));\n\t}\n};\nModelRange.prototype.is = function(type) {\n\treturn type === \"range\" || type === \"model:range\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/conversion/mapper\n*/\nconst MapperBase = /* #__PURE__ */ EmitterMixin();\nconst MapperCacheBase = /* #__PURE__ */ EmitterMixin();\n/**\n* Maps elements, positions and markers between the {@link module:engine/view/document~ViewDocument view} and\n* the {@link module:engine/model/model model}.\n*\n* The instance of the Mapper used for the editing pipeline is available in\n* {@link module:engine/controller/editingcontroller~EditingController#mapper `editor.editing.mapper`}.\n*\n* Mapper uses bound elements to find corresponding elements and positions, so, to get proper results,\n* all model elements should be {@link module:engine/conversion/mapper~Mapper#bindElements bound}.\n*\n* To map the complex model to/from view relations, you may provide custom callbacks for the\n* {@link module:engine/conversion/mapper~Mapper#event:modelToViewPosition modelToViewPosition event} and\n* {@link module:engine/conversion/mapper~Mapper#event:viewToModelPosition viewToModelPosition event} that are fired whenever\n* a position mapping request occurs.\n* Those events are fired by the {@link module:engine/conversion/mapper~Mapper#toViewPosition toViewPosition}\n* and {@link module:engine/conversion/mapper~Mapper#toModelPosition toModelPosition} methods. `Mapper` adds its own default callbacks\n* with `'lowest'` priority. To override default `Mapper` mapping, add custom callback with higher priority and\n* stop the event.\n*/\nvar Mapper = class extends MapperBase {\n\t/**\n\t* Model element to view element mapping.\n\t*/\n\t_modelToViewMapping = /* @__PURE__ */ new WeakMap();\n\t/**\n\t* View element to model element mapping.\n\t*/\n\t_viewToModelMapping = /* @__PURE__ */ new WeakMap();\n\t/**\n\t* A map containing callbacks between view element names and functions evaluating length of view elements\n\t* in model.\n\t*/\n\t_viewToModelLengthCallbacks = /* @__PURE__ */ new Map();\n\t/**\n\t* Model marker name to view elements mapping.\n\t*\n\t* Keys are `String`s while values are `Set`s with {@link module:engine/view/element~ViewElement view elements}.\n\t* One marker (name) can be mapped to multiple elements.\n\t*/\n\t_markerNameToElements = /* @__PURE__ */ new Map();\n\t/**\n\t* View element to model marker names mapping.\n\t*\n\t* This is reverse to {@link ~Mapper#_markerNameToElements} map.\n\t*/\n\t_elementToMarkerNames = /* @__PURE__ */ new Map();\n\t/**\n\t* The map of removed view elements with their current root (used for deferred unbinding).\n\t*/\n\t_deferredBindingRemovals = /* @__PURE__ */ new Map();\n\t/**\n\t* Stores marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element\n\t* has been removed, moved or renamed).\n\t*/\n\t_unboundMarkerNames = /* @__PURE__ */ new Set();\n\t/**\n\t* Manages dynamic cache for the `Mapper` to improve the performance.\n\t*/\n\t_cache = new MapperCache();\n\t/**\n\t* Creates an instance of the mapper.\n\t*/\n\tconstructor() {\n\t\tsuper();\n\t\tthis.on(\"modelToViewPosition\", (evt, data) => {\n\t\t\tif (data.viewPosition) return;\n\t\t\tconst viewContainer = this._modelToViewMapping.get(data.modelPosition.parent);\n\t\t\tif (!viewContainer)\n /**\n\t\t\t* A model position could not be mapped to the view because the parent of the model position\n\t\t\t* does not have a mapped view element (might have not been converted yet or it has no converter).\n\t\t\t*\n\t\t\t* Make sure that the model element is correctly converted to the view.\n\t\t\t*\n\t\t\t* @error mapping-model-position-view-parent-not-found\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"mapping-model-position-view-parent-not-found\", this, { modelPosition: data.modelPosition });\n\t\t\tdata.viewPosition = this.findPositionIn(viewContainer, data.modelPosition.offset);\n\t\t}, { priority: \"low\" });\n\t\tthis.on(\"viewToModelPosition\", (evt, data) => {\n\t\t\tif (data.modelPosition) return;\n\t\t\tconst viewBlock = this.findMappedViewAncestor(data.viewPosition);\n\t\t\tconst modelParent = this._viewToModelMapping.get(viewBlock);\n\t\t\tconst modelOffset = this._toModelOffset(data.viewPosition.parent, data.viewPosition.offset, viewBlock);\n\t\t\tdata.modelPosition = ModelPosition._createAt(modelParent, modelOffset);\n\t\t}, { priority: \"low\" });\n\t}\n\t/**\n\t* Marks model and view elements as corresponding. Corresponding elements can be retrieved by using\n\t* the {@link module:engine/conversion/mapper~Mapper#toModelElement toModelElement} and\n\t* {@link module:engine/conversion/mapper~Mapper#toViewElement toViewElement} methods.\n\t* The information that elements are bound is also used to translate positions.\n\t*\n\t* @param modelElement Model element.\n\t* @param viewElement View element.\n\t*/\n\tbindElements(modelElement, viewElement) {\n\t\tthis._modelToViewMapping.set(modelElement, viewElement);\n\t\tthis._viewToModelMapping.set(viewElement, modelElement);\n\t}\n\t/**\n\t* Unbinds the given {@link module:engine/view/element~ViewElement view element} from the map.\n\t*\n\t* **Note:** view-to-model binding will be removed, if it existed. However, corresponding model-to-view binding\n\t* will be removed only if model element is still bound to the passed `viewElement`.\n\t*\n\t* This behavior allows for re-binding model element to another view element without fear of losing the new binding\n\t* when the previously bound view element is unbound.\n\t*\n\t* @param viewElement View element to unbind.\n\t* @param options The options object.\n\t* @param options.defer Controls whether the binding should be removed immediately or deferred until a\n\t* {@link #flushDeferredBindings `flushDeferredBindings()`} call.\n\t*/\n\tunbindViewElement(viewElement, options = {}) {\n\t\tconst modelElement = this.toModelElement(viewElement);\n\t\tif (this._elementToMarkerNames.has(viewElement)) for (const markerName of this._elementToMarkerNames.get(viewElement)) this._unboundMarkerNames.add(markerName);\n\t\tif (options.defer) this._deferredBindingRemovals.set(viewElement, viewElement.root);\n\t\telse {\n\t\t\tif (this._viewToModelMapping.delete(viewElement)) this._cache.stopTracking(viewElement);\n\t\t\tif (this._modelToViewMapping.get(modelElement) == viewElement) this._modelToViewMapping.delete(modelElement);\n\t\t}\n\t}\n\t/**\n\t* Unbinds the given {@link module:engine/model/element~ModelElement model element} from the map.\n\t*\n\t* **Note:** the model-to-view binding will be removed, if it existed. However, the corresponding view-to-model binding\n\t* will be removed only if the view element is still bound to the passed `modelElement`.\n\t*\n\t* This behavior lets for re-binding view element to another model element without fear of losing the new binding\n\t* when the previously bound model element is unbound.\n\t*\n\t* @param modelElement Model element to unbind.\n\t*/\n\tunbindModelElement(modelElement) {\n\t\tconst viewElement = this.toViewElement(modelElement);\n\t\tthis._modelToViewMapping.delete(modelElement);\n\t\tif (this._viewToModelMapping.get(viewElement) == modelElement) {\n\t\t\t/* v8 ignore next 4 -- @preserve */\n\t\t\tif (this._viewToModelMapping.delete(viewElement)) this._cache.stopTracking(viewElement);\n\t\t}\n\t}\n\t/**\n\t* Binds the given marker name with the given {@link module:engine/view/element~ViewElement view element}. The element\n\t* will be added to the current set of elements bound with the given marker name.\n\t*\n\t* @param element Element to bind.\n\t* @param name Marker name.\n\t*/\n\tbindElementToMarker(element, name) {\n\t\tconst elements = this._markerNameToElements.get(name) || /* @__PURE__ */ new Set();\n\t\telements.add(element);\n\t\tconst names = this._elementToMarkerNames.get(element) || /* @__PURE__ */ new Set();\n\t\tnames.add(name);\n\t\tthis._markerNameToElements.set(name, elements);\n\t\tthis._elementToMarkerNames.set(element, names);\n\t}\n\t/**\n\t* Unbinds an element from given marker name.\n\t*\n\t* @param element Element to unbind.\n\t* @param name Marker name.\n\t*/\n\tunbindElementFromMarkerName(element, name) {\n\t\tconst nameToElements = this._markerNameToElements.get(name);\n\t\tif (nameToElements) {\n\t\t\tnameToElements.delete(element);\n\t\t\tif (nameToElements.size == 0) this._markerNameToElements.delete(name);\n\t\t}\n\t\tconst elementToNames = this._elementToMarkerNames.get(element);\n\t\tif (elementToNames) {\n\t\t\telementToNames.delete(name);\n\t\t\tif (elementToNames.size == 0) this._elementToMarkerNames.delete(element);\n\t\t}\n\t}\n\t/**\n\t* Returns all marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element\n\t* has been removed, moved or renamed) since the last flush. After returning, the marker names list is cleared.\n\t*/\n\tflushUnboundMarkerNames() {\n\t\tconst markerNames = Array.from(this._unboundMarkerNames);\n\t\tthis._unboundMarkerNames.clear();\n\t\treturn markerNames;\n\t}\n\t/**\n\t* Unbinds all deferred binding removals of view elements that in the meantime were not re-attached to some root or document fragment.\n\t*\n\t* See: {@link #unbindViewElement `unbindViewElement()`}.\n\t*/\n\tflushDeferredBindings() {\n\t\tfor (const [viewElement, root] of this._deferredBindingRemovals) if (viewElement.root == root) this.unbindViewElement(viewElement);\n\t\tthis._deferredBindingRemovals = /* @__PURE__ */ new Map();\n\t}\n\t/**\n\t* Removes all model to view and view to model bindings.\n\t*/\n\tclearBindings() {\n\t\tthis._modelToViewMapping = /* @__PURE__ */ new WeakMap();\n\t\tthis._viewToModelMapping = /* @__PURE__ */ new WeakMap();\n\t\tthis._markerNameToElements = /* @__PURE__ */ new Map();\n\t\tthis._elementToMarkerNames = /* @__PURE__ */ new Map();\n\t\tthis._unboundMarkerNames = /* @__PURE__ */ new Set();\n\t\tthis._deferredBindingRemovals = /* @__PURE__ */ new Map();\n\t}\n\ttoModelElement(viewElement) {\n\t\treturn this._viewToModelMapping.get(viewElement);\n\t}\n\ttoViewElement(modelElement) {\n\t\treturn this._modelToViewMapping.get(modelElement);\n\t}\n\t/**\n\t* Gets the corresponding model range.\n\t*\n\t* @param viewRange View range.\n\t* @returns Corresponding model range.\n\t*/\n\ttoModelRange(viewRange) {\n\t\treturn new ModelRange(this.toModelPosition(viewRange.start), this.toModelPosition(viewRange.end));\n\t}\n\t/**\n\t* Gets the corresponding view range.\n\t*\n\t* @param modelRange Model range.\n\t* @returns Corresponding view range.\n\t*/\n\ttoViewRange(modelRange) {\n\t\treturn new ViewRange(this.toViewPosition(modelRange.start), this.toViewPosition(modelRange.end));\n\t}\n\t/**\n\t* Gets the corresponding model position.\n\t*\n\t* @fires viewToModelPosition\n\t* @param viewPosition View position.\n\t* @returns Corresponding model position.\n\t*/\n\ttoModelPosition(viewPosition) {\n\t\tconst data = {\n\t\t\tviewPosition,\n\t\t\tmapper: this\n\t\t};\n\t\tthis.fire(\"viewToModelPosition\", data);\n\t\treturn data.modelPosition;\n\t}\n\t/**\n\t* Gets the corresponding view position.\n\t*\n\t* @fires modelToViewPosition\n\t* @param modelPosition Model position.\n\t* @param options Additional options for position mapping process.\n\t* @param options.isPhantom Should be set to `true` if the model position to map is pointing to a place\n\t* in model tree which no longer exists. For example, it could be an end of a removed model range.\n\t* @returns Corresponding view position.\n\t*/\n\ttoViewPosition(modelPosition, options = {}) {\n\t\tconst data = {\n\t\t\tmodelPosition,\n\t\t\tmapper: this,\n\t\t\tisPhantom: options.isPhantom\n\t\t};\n\t\tthis.fire(\"modelToViewPosition\", data);\n\t\treturn data.viewPosition;\n\t}\n\t/**\n\t* Gets all view elements bound to the given marker name.\n\t*\n\t* @param name Marker name.\n\t* @returns View elements bound with the given marker name or `null`\n\t* if no elements are bound to the given marker name.\n\t*/\n\tmarkerNameToElements(name) {\n\t\tconst boundElements = this._markerNameToElements.get(name);\n\t\tif (!boundElements) return null;\n\t\tconst elements = /* @__PURE__ */ new Set();\n\t\tfor (const element of boundElements) if (element.is(\"attributeElement\")) for (const clone of element.getElementsWithSameId()) elements.add(clone);\n\t\telse elements.add(element);\n\t\treturn elements;\n\t}\n\t/**\n\t* **This method is deprecated and will be removed in one of the future CKEditor 5 releases.**\n\t*\n\t* **Using this method will turn off `Mapper` caching system and may degrade performance when operating on bigger documents.**\n\t*\n\t* Registers a callback that evaluates the length in the model of a view element with the given name.\n\t*\n\t* The callback is fired with one argument, which is a view element instance. The callback is expected to return\n\t* a number representing the length of the view element in the model.\n\t*\n\t* ```ts\n\t* // List item in view may contain nested list, which have other list items. In model though,\n\t* // the lists are represented by flat structure. Because of those differences, length of list view element\n\t* // may be greater than one. In the callback it's checked how many nested list items are in evaluated list item.\n\t*\n\t* function getViewListItemLength( element ) {\n\t* \tlet length = 1;\n\t*\n\t* \tfor ( let child of element.getChildren() ) {\n\t* \t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t* \t\t\tfor ( let item of child.getChildren() ) {\n\t* \t\t\t\tlength += getViewListItemLength( item );\n\t* \t\t\t}\n\t* \t\t}\n\t* \t}\n\t*\n\t* \treturn length;\n\t* }\n\t*\n\t* mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t* ```\n\t*\n\t* @param viewElementName Name of view element for which callback is registered.\n\t* @param lengthCallback Function return a length of view element instance in model.\n\t* @deprecated\n\t*/\n\tregisterViewToModelLength(viewElementName, lengthCallback) {\n\t\tthis._viewToModelLengthCallbacks.set(viewElementName, lengthCallback);\n\t}\n\t/**\n\t* For the given `viewPosition`, finds and returns the closest ancestor of this position that has a mapping to\n\t* the model.\n\t*\n\t* @param viewPosition Position for which a mapped ancestor should be found.\n\t*/\n\tfindMappedViewAncestor(viewPosition) {\n\t\tlet parent = viewPosition.parent;\n\t\twhile (!this._viewToModelMapping.has(parent)) parent = parent.parent;\n\t\treturn parent;\n\t}\n\t/**\n\t* Calculates model offset based on the view position and the block element.\n\t*\n\t* Example:\n\t*\n\t* ```html\n\t* <p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, p ) -> 5\n\t* ```\n\t*\n\t* Is a sum of:\n\t*\n\t* ```html\n\t* <p>foo|<b>bar</b></p> // _toModelOffset( p, 3, p ) -> 3\n\t* <p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, b ) -> 2\n\t* ```\n\t*\n\t* @param viewParent Position parent.\n\t* @param viewOffset Position offset.\n\t* @param viewBlock Block used as a base to calculate offset.\n\t* @returns Offset in the model.\n\t*/\n\t_toModelOffset(viewParent, viewOffset, viewBlock) {\n\t\tif (viewBlock != viewParent) return this._toModelOffset(viewParent.parent, viewParent.index, viewBlock) + this._toModelOffset(viewParent, viewOffset, viewParent);\n\t\tif (viewParent.is(\"$text\")) return viewOffset;\n\t\tlet modelOffset = 0;\n\t\tfor (let i = 0; i < viewOffset; i++) modelOffset += this.getModelLength(viewParent.getChild(i));\n\t\treturn modelOffset;\n\t}\n\t/**\n\t* Gets the length of the view element in the model.\n\t*\n\t* The length is calculated as follows:\n\t* * if a {@link #registerViewToModelLength length mapping callback} is provided for the given `viewNode`, it is used to\n\t* evaluate the model length (`viewNode` is used as first and only parameter passed to the callback),\n\t* * length of a {@link module:engine/view/text~ViewText text node} is equal to the length of its\n\t* {@link module:engine/view/text~ViewText#data data},\n\t* * length of a {@link module:engine/view/uielement~ViewUIElement ui element} is equal to 0,\n\t* * length of a mapped {@link module:engine/view/element~ViewElement element} is equal to 1,\n\t* * length of a non-mapped {@link module:engine/view/element~ViewElement element} is equal to the length of its children.\n\t*\n\t* Examples:\n\t*\n\t* ```\n\t* foo -> 3 // Text length is equal to its data length.\n\t* <p>foo</p> -> 1 // Length of an element which is mapped is by default equal to 1.\n\t* <b>foo</b> -> 3 // Length of an element which is not mapped is a length of its children.\n\t* <div><p>x</p><p>y</p></div> -> 2 // Assuming that <div> is not mapped and <p> are mapped.\n\t* ```\n\t*\n\t* @param viewNode View node.\n\t* @returns Length of the node in the tree model.\n\t*/\n\tgetModelLength(viewNode) {\n\t\tconst stack = [viewNode];\n\t\tlet len = 0;\n\t\twhile (stack.length > 0) {\n\t\t\tconst node = stack.pop();\n\t\t\tconst callback = node.name && this._viewToModelLengthCallbacks.size > 0 && this._viewToModelLengthCallbacks.get(node.name);\n\t\t\tif (callback) len += callback(node);\n\t\t\telse if (this._viewToModelMapping.has(node)) len += 1;\n\t\t\telse if (node.is(\"$text\")) len += node.data.length;\n\t\t\telse if (node.is(\"uiElement\")) continue;\n\t\t\telse for (const child of node.getChildren()) stack.push(child);\n\t\t}\n\t\treturn len;\n\t}\n\t/**\n\t* Finds the position in a view element or view document fragment node (or in its children) with the expected model offset.\n\t*\n\t* If the passed `viewContainer` is bound to model, `Mapper` will use caching mechanism to improve performance.\n\t*\n\t* @param viewContainer Tree view element in which we are looking for the position.\n\t* @param modelOffset Expected offset.\n\t* @returns Found position.\n\t*/\n\tfindPositionIn(viewContainer, modelOffset) {\n\t\tif (modelOffset === 0) return this._moveViewPositionToTextNode(new ViewPosition(viewContainer, 0));\n\t\tif (this._viewToModelLengthCallbacks.size == 0 && this._viewToModelMapping.has(viewContainer)) {\n\t\t\tconst cacheItem = this._cache.getClosest(viewContainer, modelOffset);\n\t\t\treturn this._findPositionStartingFrom(cacheItem.viewPosition, cacheItem.modelOffset, modelOffset, viewContainer, true);\n\t\t} else return this._findPositionStartingFrom(new ViewPosition(viewContainer, 0), 0, modelOffset, viewContainer, false);\n\t}\n\t/**\n\t* Performs most of the logic for `Mapper#findPositionIn()`.\n\t*\n\t* It allows to start looking for the requested model offset from a given starting position, to enable caching. Using the cache,\n\t* you can set the starting point and skip all the calculations that were already previously done.\n\t*\n\t* This method uses recursion to find positions inside deep structures. Example:\n\t*\n\t* ```\n\t* <p>fo<b>bar</b>bom</p> -> target offset: 4\n\t* <p>|fo<b>bar</b>bom</p> -> target offset: 4, traversed offset: 0\n\t* <p>fo|<b>bar</b>bom</p> -> target offset: 4, traversed offset: 2\n\t* <p>fo<b>bar</b>|bom</p> -> target offset: 4, traversed offset: 5 -> we are too far, look recursively in <b>.\n\t*\n\t* <p>fo<b>|bar</b>bom</p> -> target offset: 4, traversed offset: 2\n\t* <p>fo<b>bar|</b>bom</p> -> target offset: 4, traversed offset: 5 -> we are too far, look inside \"bar\".\n\t*\n\t* <p>fo<b>ba|r</b>bom</p> -> target offset: 4, traversed offset: 2 -> position is inside text node at offset 4-2 = 2.\n\t* ```\n\t*\n\t* @param startViewPosition View position to start looking from.\n\t* @param startModelOffset Model offset related to `startViewPosition`.\n\t* @param targetModelOffset Target model offset to find.\n\t* @param viewContainer Mapped ancestor of `startViewPosition`. `startModelOffset` is the offset inside a model element or model\n\t* document fragment mapped to `viewContainer`.\n\t* @param useCache Whether `Mapper` should cache positions while traversing the view tree looking for `expectedModelOffset`.\n\t* @returns View position mapped to `targetModelOffset`.\n\t*/\n\t_findPositionStartingFrom(startViewPosition, startModelOffset, targetModelOffset, viewContainer, useCache) {\n\t\tlet viewParent = startViewPosition.parent;\n\t\tlet viewOffset = startViewPosition.offset;\n\t\tif (viewParent.is(\"$text\")) return new ViewPosition(viewParent, targetModelOffset - startModelOffset);\n\t\tlet viewNode;\n\t\tlet traversedModelOffset = startModelOffset;\n\t\tlet lastLength = 0;\n\t\twhile (traversedModelOffset < targetModelOffset) {\n\t\t\tviewNode = viewParent.getChild(viewOffset);\n\t\t\tif (!viewNode) if (viewParent == viewContainer)\n /**\n\t\t\t* A model position could not be mapped to the view because specified model offset was too big and could not be\n\t\t\t* found inside the mapped view element or view document fragment.\n\t\t\t*\n\t\t\t* @error mapping-model-offset-not-found\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"mapping-model-offset-not-found\", this, {\n\t\t\t\tmodelOffset: targetModelOffset,\n\t\t\t\tviewContainer\n\t\t\t});\n\t\t\telse {\n\t\t\t\tviewOffset = viewParent.parent.getChildIndex(viewParent) + 1;\n\t\t\t\tviewParent = viewParent.parent;\n\t\t\t\tif (useCache) this._cache.save(viewParent, viewOffset, viewContainer, traversedModelOffset);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (useCache) lastLength = this._getModelLengthAndCache(viewNode, viewContainer, traversedModelOffset);\n\t\t\telse lastLength = this.getModelLength(viewNode);\n\t\t\ttraversedModelOffset += lastLength;\n\t\t\tviewOffset++;\n\t\t}\n\t\tlet viewPosition = new ViewPosition(viewParent, viewOffset);\n\t\tif (useCache) while (viewPosition.isAtEnd && viewPosition.parent !== viewContainer && viewPosition.parent.parent) {\n\t\t\tconst cacheViewParent = viewPosition.parent.parent;\n\t\t\tconst cacheViewOffset = cacheViewParent.getChildIndex(viewPosition.parent) + 1;\n\t\t\tthis._cache.save(cacheViewParent, cacheViewOffset, viewContainer, traversedModelOffset);\n\t\t\tviewPosition = new ViewPosition(cacheViewParent, cacheViewOffset);\n\t\t}\n\t\tif (traversedModelOffset == targetModelOffset) return this._moveViewPositionToTextNode(viewPosition);\n\t\telse return this._findPositionStartingFrom(new ViewPosition(viewNode, 0), traversedModelOffset - lastLength, targetModelOffset, viewContainer, useCache);\n\t}\n\t/**\n\t* Gets the length of the view element in the model and updates cache values after each view item it visits.\n\t*\n\t* See also {@link #getModelLength}.\n\t*\n\t* @param viewNode View node.\n\t* @param viewContainer Ancestor of `viewNode` that is a mapped view element.\n\t* @param modelOffset Model offset at which the `viewNode` starts.\n\t* @returns Length of the node in the tree model.\n\t*/\n\t_getModelLengthAndCache(viewNode, viewContainer, modelOffset) {\n\t\tlet len = 0;\n\t\tif (this._viewToModelMapping.has(viewNode)) len = 1;\n\t\telse if (viewNode.is(\"$text\")) len = viewNode.data.length;\n\t\telse if (!viewNode.is(\"uiElement\")) for (const child of viewNode.getChildren()) len += this._getModelLengthAndCache(child, viewContainer, modelOffset + len);\n\t\tthis._cache.save(viewNode.parent, viewNode.index + 1, viewContainer, modelOffset + len);\n\t\treturn len;\n\t}\n\t/**\n\t* Because we prefer positions in the text nodes over positions next to text nodes, if the view position was next to a text node,\n\t* it moves it into the text node instead.\n\t*\n\t* ```\n\t* <p>[]<b>foo</b></p> -> <p>[]<b>foo</b></p> // do not touch if position is not directly next to text\n\t* <p>foo[]<b>foo</b></p> -> <p>foo{}<b>foo</b></p> // move to text node\n\t* <p><b>[]foo</b></p> -> <p><b>{}foo</b></p> // move to text node\n\t* ```\n\t*\n\t* @param viewPosition Position potentially next to the text node.\n\t* @returns Position in the text node if possible.\n\t*/\n\t_moveViewPositionToTextNode(viewPosition) {\n\t\tconst nodeBefore = viewPosition.nodeBefore;\n\t\tconst nodeAfter = viewPosition.nodeAfter;\n\t\tif (nodeBefore && nodeBefore.is(\"view:$text\")) return new ViewPosition(nodeBefore, nodeBefore.data.length);\n\t\telse if (nodeAfter && nodeAfter.is(\"view:$text\")) return new ViewPosition(nodeAfter, 0);\n\t\treturn viewPosition;\n\t}\n};\n/**\n* Cache mechanism for {@link module:engine/conversion/mapper~Mapper Mapper}.\n*\n* `MapperCache` improves performance for model-to-view position mapping, which is the main `Mapper` task. Asking for a mapping is much\n* more frequent than actually performing changes, and even if the change happens, we can still partially keep the cache. This makes\n* caching a useful strategy for `Mapper`.\n*\n* `MapperCache` will store some data for view elements or view document fragments that are mapped by the `Mapper`. These view items\n* are \"tracked\" by the `MapperCache`. For such view items, we will keep entries of model offsets inside their mapped counterpart. For\n* the cached model offsets, we will keep a view position that is inside the tracked item. This allows us to either get the mapping\n* instantly, or at least in less steps than when calculating it from the beginning.\n*\n* Important problem related to caching is invalidating the cache. The cache must be invalidated each time the tracked view item changes.\n* Additionally, we should invalidate as small part of the cache as possible. Since all the logic is encapsulated inside `MapperCache`,\n* the `MapperCache` listens to view items {@link module:engine/view/node~ViewNodeChangeEvent `change` event} and reacts to it.\n* Then, it invalidates just the part of the cache that is \"after\" the changed part of the view.\n*\n* As mentioned, `MapperCache` currently is used only for model-to-view position mapping as it was much bigger problem than view-to-model\n* mapping. However, it should be possible to use it also for view-to-model.\n*\n* The main assumptions regarding `MapperCache` are:\n*\n* * it is an internal tool, used by `Mapper`, transparent to the outside (no additional effort when developing a plugin or a converter),\n* * it stores all the necessary data internally, which makes it easier to disable or debug,\n* * it is optimized for initial downcast process (long insertions), which is crucial for editor init and data save,\n* * it does not save all possible positions mapping for memory considerations, although it is a possible improvement, which may increase\n* performance, as well as simplify some parts of the `MapperCache` logic.\n*\n* @internal\n*/\nvar MapperCache = class extends MapperCacheBase {\n\t/**\n\t* For every view element or document fragment tracked by `MapperCache`, it holds currently cached data, or more precisely,\n\t* model offset to view position mappings. See also `MappingCache` and `CacheItem`.\n\t*\n\t* If an item is tracked by `MapperCache` it has an entry in this structure, so this structure can be used to check which items\n\t* are tracked by `MapperCache`. When an item is no longer tracked, it is removed from this structure.\n\t*\n\t* Although `MappingCache` and `CacheItem` structures allows for caching any model offsets and view positions, we only cache\n\t* values for model offsets that are after a view node. So, in essence, positions inside text nodes are not cached. However, it takes\n\t* from one to at most a few steps, to get from a cached position to a position that is inside a view text node.\n\t*\n\t* Additionally, only one item per `modelOffset` is cached. There can be several view positions that map to the same `modelOffset`.\n\t* Only the first save for `modelOffset` is stored.\n\t*/\n\t_cachedMapping = /* @__PURE__ */ new WeakMap();\n\t/**\n\t* When `MapperCache` {@link ~MapperCache#save saves} view position -> model offset mapping, a `CacheItem` is inserted into certain\n\t* `MappingCache#cacheList` at some index. Additionally, we store that index with the view node that is before the cached view position.\n\t*\n\t* This allows to quickly get a cache list item related to certain view node, and hence, for fast cache invalidation.\n\t*\n\t* For example, consider view: `<p>Some <strong>bold</strong> text.</p>`, where `<p>` is a view element tracked by `MapperCache`.\n\t* If all `<p>` children were visited by `MapperCache`, then `<p>` cache list would have four items, related to following model offsets:\n\t* `0`, `5`, `9`, `15`. Then, view node `\"Some \"` would have index `1`, `<strong>` index `2`, and `\" text.\" index `3`.\n\t*\n\t* Note that the index related with a node is always greater than `0`. The first item in cache list is always for model offset `0`\n\t* (and view offset `0`), and it is not related to any node.\n\t*/\n\t_nodeToCacheListIndex = /* @__PURE__ */ new WeakMap();\n\t/**\n\t* Callback fired whenever there is a direct or indirect children change in tracked view element or tracked view document fragment.\n\t*\n\t* This is specified as a property to make it easier to set as an event callback and to later turn off that event.\n\t*/\n\t_invalidateOnChildrenChangeCallback = (evt, viewNode, data) => {\n\t\tthis._clearCacheInsideParent(viewNode, data.index);\n\t};\n\t/**\n\t* Callback fired whenever a view text node directly or indirectly inside a tracked view element or tracked view document fragment\n\t* changes its text data.\n\t*\n\t* This is specified as a property to make it easier to set as an event callback and to later turn off that event.\n\t*/\n\t_invalidateOnTextChangeCallback = (evt, viewNode) => {\n\t\tthis._clearCacheAfter(viewNode);\n\t};\n\t/**\n\t* Saves cache for given view position mapping <-> model offset mapping. The view position should be after a node (i.e. it cannot\n\t* be the first position inside its parent, or in other words, `viewOffset` must be greater than `0`).\n\t*\n\t* Note, that if `modelOffset` for given `viewContainer` was already saved, the stored view position (i.e. parent+offset) will not\n\t* be overwritten. However, it is important to still save it, as we still store additional data related to cached view positions.\n\t*\n\t* @param viewParent View position parent.\n\t* @param viewOffset View position offset. Must be greater than `0`.\n\t* @param viewContainer Tracked view position ascendant (it may be the direct parent of the view position).\n\t* @param modelOffset Model offset in the model element or document fragment which is mapped to `viewContainer`.\n\t*/\n\tsave(viewParent, viewOffset, viewContainer, modelOffset) {\n\t\tconst cache = this._cachedMapping.get(viewContainer);\n\t\tconst cacheItem = cache.cacheMap.get(modelOffset);\n\t\tif (cacheItem) {\n\t\t\tconst viewChild = viewParent.getChild(viewOffset - 1);\n\t\t\tconst index = cacheItem.viewPosition.nodeBefore ? this._nodeToCacheListIndex.get(cacheItem.viewPosition.nodeBefore) : 0;\n\t\t\tthis._nodeToCacheListIndex.set(viewChild, index);\n\t\t\treturn;\n\t\t}\n\t\tconst newCacheItem = {\n\t\t\tviewPosition: new ViewPosition(viewParent, viewOffset),\n\t\t\tmodelOffset\n\t\t};\n\t\tcache.maxModelOffset = modelOffset > cache.maxModelOffset ? modelOffset : cache.maxModelOffset;\n\t\tcache.cacheMap.set(modelOffset, newCacheItem);\n\t\tlet i = cache.cacheList.length - 1;\n\t\twhile (i >= 0 && cache.cacheList[i].modelOffset > modelOffset) i--;\n\t\tcache.cacheList.splice(i + 1, 0, newCacheItem);\n\t\tif (viewOffset > 0) {\n\t\t\tconst viewChild = viewParent.getChild(viewOffset - 1);\n\t\t\tthis._nodeToCacheListIndex.set(viewChild, i + 1);\n\t\t}\n\t}\n\t/**\n\t* For given `modelOffset` inside a model element mapped to given `viewContainer`, it returns the closest saved cache item\n\t* (view position and related model offset) to the requested one.\n\t*\n\t* It can be exactly the requested mapping, or it can be mapping that is the closest starting point to look for the requested mapping.\n\t*\n\t* `viewContainer` must be a view element or document fragment that is mapped by the {@link ~Mapper Mapper}.\n\t*\n\t* If `viewContainer` is not yet tracked by the `MapperCache`, it will be automatically tracked after calling this method.\n\t*\n\t* Note: this method will automatically \"hoist\" cached positions, i.e. it will return a position that is closest to the tracked element.\n\t*\n\t* For example, if `<p>` is tracked element, and `^` is cached position:\n\t*\n\t* ```\n\t* <p>This is <strong>some <em>heavily <u>formatted</u>^</em></strong> text.</p>\n\t* ```\n\t*\n\t* If this position would be returned, instead, a position directly in `<p>` would be returned:\n\t*\n\t* ```\n\t* <p>This is <strong>some <em>heavily <u>formatted</u></em></strong>^ text.</p>\n\t* ```\n\t*\n\t* Note, that `modelOffset` for both positions is the same.\n\t*\n\t* @param viewContainer Tracked view element or document fragment, which cache will be used.\n\t* @param modelOffset Model offset in a model element or document fragment, which is mapped to `viewContainer`.\n\t*/\n\tgetClosest(viewContainer, modelOffset) {\n\t\tconst cache = this._cachedMapping.get(viewContainer);\n\t\tlet result;\n\t\tif (cache) if (modelOffset > cache.maxModelOffset) result = cache.cacheList[cache.cacheList.length - 1];\n\t\telse {\n\t\t\tconst cacheItem = cache.cacheMap.get(modelOffset);\n\t\t\tif (cacheItem) result = cacheItem;\n\t\t\telse result = this._findInCacheList(cache.cacheList, modelOffset);\n\t\t}\n\t\telse result = this.startTracking(viewContainer);\n\t\treturn {\n\t\t\tmodelOffset: result.modelOffset,\n\t\t\tviewPosition: result.viewPosition.clone()\n\t\t};\n\t}\n\t/**\n\t* Starts tracking given `viewContainer`, which must be mapped to a model element or model document fragment.\n\t*\n\t* Note, that this method is automatically called by\n\t* {@link module:engine/conversion/mapper~MapperCache#getClosest `MapperCache#getClosest()`} and there is no need to call it manually.\n\t*\n\t* This method initializes the cache for `viewContainer` and adds callbacks for\n\t* {@link module:engine/view/node~ViewNodeChangeEvent `change` event} fired by `viewContainer`. `MapperCache` listens to `change` event\n\t* on the tracked elements to invalidate the stored cache.\n\t*/\n\tstartTracking(viewContainer) {\n\t\tconst initialCacheItem = {\n\t\t\tviewPosition: new ViewPosition(viewContainer, 0),\n\t\t\tmodelOffset: 0\n\t\t};\n\t\tconst initialCache = {\n\t\t\tmaxModelOffset: 0,\n\t\t\tcacheList: [initialCacheItem],\n\t\t\tcacheMap: /* @__PURE__ */ new Map([[0, initialCacheItem]])\n\t\t};\n\t\tthis._cachedMapping.set(viewContainer, initialCache);\n\t\tviewContainer.on(\"change:children\", this._invalidateOnChildrenChangeCallback);\n\t\tviewContainer.on(\"change:text\", this._invalidateOnTextChangeCallback);\n\t\treturn initialCacheItem;\n\t}\n\t/**\n\t* Stops tracking given `viewContainer`.\n\t*\n\t* It removes the cached data and stops listening to {@link module:engine/view/node~ViewNodeChangeEvent `change` event} on the\n\t* `viewContainer`.\n\t*/\n\tstopTracking(viewContainer) {\n\t\tviewContainer.off(\"change:children\", this._invalidateOnChildrenChangeCallback);\n\t\tviewContainer.off(\"change:text\", this._invalidateOnTextChangeCallback);\n\t\tthis._cachedMapping.delete(viewContainer);\n\t}\n\t/**\n\t* Invalidates cache inside `viewParent`, starting from given `index` in that parent.\n\t*\n\t* This method may clear a bit more cache than just what was saved after given `index`, but it is guaranteed that at least it\n\t* will invalidate everything after `index`.\n\t*/\n\t_clearCacheInsideParent(viewParent, index) {\n\t\tif (index == 0) if (this._cachedMapping.has(viewParent)) this._clearCacheAll(viewParent);\n\t\telse this._clearCacheInsideParent(viewParent.parent, viewParent.index);\n\t\telse {\n\t\t\tconst lastValidNode = viewParent.getChild(index - 1);\n\t\t\tthis._clearCacheAfter(lastValidNode);\n\t\t}\n\t}\n\t/**\n\t* Clears all the cache for given tracked `viewContainer`.\n\t*/\n\t_clearCacheAll(viewContainer) {\n\t\tconst cache = this._cachedMapping.get(viewContainer);\n\t\tif (cache.maxModelOffset > 0) {\n\t\t\tcache.maxModelOffset = 0;\n\t\t\tcache.cacheList.length = 1;\n\t\t\tcache.cacheMap.clear();\n\t\t\tcache.cacheMap.set(0, cache.cacheList[0]);\n\t\t}\n\t}\n\t/**\n\t* Clears all the stored cache that is after given `viewNode`. The `viewNode` can be any node that is inside a tracked view element\n\t* or view document fragment.\n\t*\n\t* In reality, this function may clear a bit more cache than just \"starting after\" `viewNode`, but it is guaranteed that at least\n\t* all cache after `viewNode` is invalidated.\n\t*/\n\t_clearCacheAfter(viewNode) {\n\t\tconst cacheListIndex = this._nodeToCacheListIndex.get(viewNode);\n\t\tif (cacheListIndex === void 0) {\n\t\t\tconst viewParent = viewNode.parent;\n\t\t\tif (!this._cachedMapping.has(viewParent)) this._clearCacheInsideParent(viewParent.parent, viewParent.index);\n\t\t\treturn;\n\t\t}\n\t\tlet viewContainer = viewNode.parent;\n\t\twhile (!this._cachedMapping.has(viewContainer)) viewContainer = viewContainer.parent;\n\t\tthis._clearCacheFromCacheIndex(viewContainer, cacheListIndex);\n\t}\n\t/**\n\t* Clears all the cache in the cache list related to given `viewContainer`, starting from `index` (inclusive).\n\t*/\n\t_clearCacheFromCacheIndex(viewContainer, index) {\n\t\tif (index === 0) index = 1;\n\t\tconst cache = this._cachedMapping.get(viewContainer);\n\t\tconst cacheItem = cache.cacheList[index - 1];\n\t\tif (!cacheItem) return;\n\t\tcache.maxModelOffset = cacheItem.modelOffset;\n\t\tconst clearedItems = cache.cacheList.splice(index);\n\t\tfor (const item of clearedItems) {\n\t\t\tcache.cacheMap.delete(item.modelOffset);\n\t\t\tconst viewNode = item.viewPosition.nodeBefore;\n\t\t\tthis._nodeToCacheListIndex.delete(viewNode);\n\t\t}\n\t}\n\t/**\n\t* Finds a cache item in the given cache list, which `modelOffset` is closest (but smaller or equal) to given `offset`.\n\t*\n\t* Since `cacheList` is a sorted array, this uses binary search to retrieve the item quickly.\n\t*/\n\t_findInCacheList(cacheList, offset) {\n\t\tlet start = 0;\n\t\tlet end = cacheList.length - 1;\n\t\tlet index = end - start >> 1;\n\t\tlet item = cacheList[index];\n\t\twhile (start < end) {\n\t\t\tif (item.modelOffset < offset) start = index + 1;\n\t\t\telse end = index - 1;\n\t\t\tindex = start + (end - start >> 1);\n\t\t\titem = cacheList[index];\n\t\t}\n\t\treturn item.modelOffset <= offset ? item : cacheList[index - 1];\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/conversion/modelconsumable\n*/\n/**\n* Manages a list of consumable values for the {@link module:engine/model/item~ModelItem model items}.\n*\n* Consumables are various aspects of the model. A model item can be broken down into separate, single properties that might be\n* taken into consideration when converting that item.\n*\n* `ModelConsumable` is used by {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} while analyzing the changed\n* parts of {@link module:engine/model/document~ModelDocument the document}. The added / changed / removed model items are broken down\n* into singular properties (the item itself and its attributes). All those parts are saved in `ModelConsumable`. Then,\n* during conversion, when the given part of a model item is converted (i.e. the view element has been inserted into the view,\n* but without attributes), the consumable value is removed from `ModelConsumable`.\n*\n* For model items, `ModelConsumable` stores consumable values of one of following types: `insert`, `addattribute:<attributeKey>`,\n* `changeattributes:<attributeKey>`, `removeattributes:<attributeKey>`.\n*\n* In most cases, it is enough to let th {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n* gather consumable values, so there is no need to use\n* the {@link module:engine/conversion/modelconsumable~ModelConsumable#add add method} directly.\n* However, it is important to understand how consumable values can be\n* {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed}.\n* See {@link module:engine/conversion/downcasthelpers default downcast converters} for more information.\n*\n* Keep in mind that one conversion event may have multiple callbacks (converters) attached to it. Each of those is\n* able to convert one or more parts of the model. However, when one of those callbacks actually converts\n* something, the others should not, because they would duplicate the results. Using `ModelConsumable` helps to avoid\n* this situation, because callbacks should only convert these values that were not yet consumed from `ModelConsumable`.\n*\n* Consuming multiple values in a single callback:\n*\n* ```ts\n* // Converter for custom `imageBlock` element that might have a `caption` element inside which changes\n* // how the image is displayed in the view:\n* //\n* // Model:\n* //\n* // [imageBlock]\n* // └─ [caption]\n* // └─ foo\n* //\n* // View:\n* //\n* // <figure>\n* // ├─ <img />\n* // └─ <caption>\n* // └─ foo\n* modelConversionDispatcher.on( 'insert:imageBlock', ( evt, data, conversionApi ) => {\n* \t// First, consume the `imageBlock` element.\n* \tconversionApi.consumable.consume( data.item, 'insert' );\n*\n* \t// Just create normal image element for the view.\n* \t// Maybe it will be \"decorated\" later.\n* \tconst viewImage = new ViewElement( 'img' );\n* \tconst insertPosition = conversionApi.mapper.toViewPosition( data.range.start );\n* \tconst viewWriter = conversionApi.writer;\n*\n* \t// Check if the `imageBlock` element has children.\n* \tif ( data.item.childCount > 0 ) {\n* \t\tconst modelCaption = data.item.getChild( 0 );\n*\n* \t\t// `modelCaption` insertion change is consumed from consumable values.\n* \t\t// It will not be converted by other converters, but it's children (probably some text) will be.\n* \t\t// Through mapping, converters for text will know where to insert contents of `modelCaption`.\n* \t\tif ( conversionApi.consumable.consume( modelCaption, 'insert' ) ) {\n* \t\t\tconst viewCaption = new ViewElement( 'figcaption' );\n*\n* \t\t\tconst viewImageHolder = new ViewElement( 'figure', null, [ viewImage, viewCaption ] );\n*\n* \t\t\tconversionApi.mapper.bindElements( modelCaption, viewCaption );\n* \t\t\tconversionApi.mapper.bindElements( data.item, viewImageHolder );\n* \t\t\tviewWriter.insert( insertPosition, viewImageHolder );\n* \t\t}\n* \t} else {\n* \t\tconversionApi.mapper.bindElements( data.item, viewImage );\n* \t\tviewWriter.insert( insertPosition, viewImage );\n* \t}\n*\n* \tevt.stop();\n* } );\n* ```\n*/\nvar ModelConsumable = class {\n\t/**\n\t* Contains list of consumable values.\n\t*/\n\t_consumable = /* @__PURE__ */ new Map();\n\t/**\n\t* For each {@link module:engine/model/textproxy~ModelTextProxy} added to `ModelConsumable`, this registry holds a parent\n\t* of that `ModelTextProxy` and the start and end indices of that `ModelTextProxy`. This allows identification of the `ModelTextProxy`\n\t* instances that point to the same part of the model but are different instances. Each distinct `ModelTextProxy`\n\t* is given a unique `Symbol` which is then registered as consumable. This process is transparent for the `ModelConsumable`\n\t* API user because whenever `ModelTextProxy` is added, tested, consumed or reverted, the internal mechanisms of\n\t* `ModelConsumable` translate `ModelTextProxy` to that unique `Symbol`.\n\t*/\n\t_textProxyRegistry = /* @__PURE__ */ new Map();\n\t/**\n\t* Adds a consumable value to the consumables list and links it with a given model item.\n\t*\n\t* ```ts\n\t* modelConsumable.add( modelElement, 'insert' ); // Add `modelElement` insertion change to consumable values.\n\t* modelConsumable.add( modelElement, 'addAttribute:bold' ); // Add `bold` attribute insertion on `modelElement` change.\n\t* modelConsumable.add( modelElement, 'removeAttribute:bold' ); // Add `bold` attribute removal on `modelElement` change.\n\t* modelConsumable.add( modelSelection, 'selection' ); // Add `modelSelection` to consumable values.\n\t* modelConsumable.add( modelRange, 'range' ); // Add `modelRange` to consumable values.\n\t* ```\n\t*\n\t* @param item Model item, range or selection that has the consumable.\n\t* @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t* Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t*/\n\tadd(item, type) {\n\t\ttype = _normalizeConsumableType(type);\n\t\tif (item instanceof ModelTextProxy) item = this._getSymbolForTextProxy(item);\n\t\tif (!this._consumable.has(item)) this._consumable.set(item, /* @__PURE__ */ new Map());\n\t\tthis._consumable.get(item).set(type, true);\n\t}\n\t/**\n\t* Removes a given consumable value from a given model item.\n\t*\n\t* ```ts\n\t* modelConsumable.consume( modelElement, 'insert' ); // Remove `modelElement` insertion change from consumable values.\n\t* modelConsumable.consume( modelElement, 'addAttribute:bold' ); // Remove `bold` attribute insertion on `modelElement` change.\n\t* modelConsumable.consume( modelElement, 'removeAttribute:bold' ); // Remove `bold` attribute removal on `modelElement` change.\n\t* modelConsumable.consume( modelSelection, 'selection' ); // Remove `modelSelection` from consumable values.\n\t* modelConsumable.consume( modelRange, 'range' ); // Remove 'modelRange' from consumable values.\n\t* ```\n\t*\n\t* @param item Model item, range or selection from which consumable will be consumed.\n\t* @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t* Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t* @returns `true` if consumable value was available and was consumed, `false` otherwise.\n\t*/\n\tconsume(item, type) {\n\t\ttype = _normalizeConsumableType(type);\n\t\tif (item instanceof ModelTextProxy) item = this._getSymbolForTextProxy(item);\n\t\tif (this.test(item, type)) {\n\t\t\tthis._consumable.get(item).set(type, false);\n\t\t\treturn true;\n\t\t} else return false;\n\t}\n\t/**\n\t* Tests whether there is a consumable value of a given type connected with a given model item.\n\t*\n\t* ```ts\n\t* modelConsumable.test( modelElement, 'insert' ); // Check for `modelElement` insertion change.\n\t* modelConsumable.test( modelElement, 'addAttribute:bold' ); // Check for `bold` attribute insertion on `modelElement` change.\n\t* modelConsumable.test( modelElement, 'removeAttribute:bold' ); // Check for `bold` attribute removal on `modelElement` change.\n\t* modelConsumable.test( modelSelection, 'selection' ); // Check if `modelSelection` is consumable.\n\t* modelConsumable.test( modelRange, 'range' ); // Check if `modelRange` is consumable.\n\t* ```\n\t*\n\t* @param item Model item, range or selection to be tested.\n\t* @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t* Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t* @returns `null` if such consumable was never added, `false` if the consumable values was\n\t* already consumed or `true` if it was added and not consumed yet.\n\t*/\n\ttest(item, type) {\n\t\ttype = _normalizeConsumableType(type);\n\t\tif (item instanceof ModelTextProxy) item = this._getSymbolForTextProxy(item);\n\t\tconst itemConsumables = this._consumable.get(item);\n\t\tif (itemConsumables === void 0) return null;\n\t\tconst value = itemConsumables.get(type);\n\t\tif (value === void 0) return null;\n\t\treturn value;\n\t}\n\t/**\n\t* Reverts consuming of a consumable value.\n\t*\n\t* ```ts\n\t* modelConsumable.revert( modelElement, 'insert' ); // Revert consuming `modelElement` insertion change.\n\t* modelConsumable.revert( modelElement, 'addAttribute:bold' ); // Revert consuming `bold` attribute insert from `modelElement`.\n\t* modelConsumable.revert( modelElement, 'removeAttribute:bold' ); // Revert consuming `bold` attribute remove from `modelElement`.\n\t* modelConsumable.revert( modelSelection, 'selection' ); // Revert consuming `modelSelection`.\n\t* modelConsumable.revert( modelRange, 'range' ); // Revert consuming `modelRange`.\n\t* ```\n\t*\n\t* @param item Model item, range or selection to be reverted.\n\t* @param type Consumable type.\n\t* @returns `true` if consumable has been reversed, `false` otherwise. `null` if the consumable has\n\t* never been added.\n\t*/\n\trevert(item, type) {\n\t\ttype = _normalizeConsumableType(type);\n\t\tif (item instanceof ModelTextProxy) item = this._getSymbolForTextProxy(item);\n\t\tconst test = this.test(item, type);\n\t\tif (test === false) {\n\t\t\tthis._consumable.get(item).set(type, true);\n\t\t\treturn true;\n\t\t} else if (test === true) return false;\n\t\treturn null;\n\t}\n\t/**\n\t* Verifies if all events from the specified group were consumed.\n\t*\n\t* @param eventGroup The events group to verify.\n\t*/\n\tverifyAllConsumed(eventGroup) {\n\t\tconst items = [];\n\t\tfor (const [item, consumables] of this._consumable) for (const [event, canConsume] of consumables) {\n\t\t\tconst eventPrefix = event.split(\":\")[0];\n\t\t\tif (canConsume && eventGroup == eventPrefix) items.push({\n\t\t\t\tevent,\n\t\t\t\titem: item.name || item.description\n\t\t\t});\n\t\t}\n\t\tif (items.length)\n /**\n\t\t* Some of the {@link module:engine/model/item~ModelItem model items} were not consumed while downcasting the model to view.\n\t\t*\n\t\t* This might be the effect of:\n\t\t*\n\t\t* * A missing converter for some model elements. Make sure that you registered downcast converters for all model elements.\n\t\t* * A custom converter that does not consume converted items. Make sure that you\n\t\t* {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} all model elements that you converted\n\t\t* from the model to the view.\n\t\t* * A custom converter that called `event.stop()`. When providing a custom converter, keep in mind that you should not stop\n\t\t* the event. If you stop it then the default converter at the `lowest` priority will not trigger the conversion of this node's\n\t\t* attributes and child nodes.\n\t\t*\n\t\t* @error conversion-model-consumable-not-consumed\n\t\t* @param {Array.<module:engine/model/item~ModelItem>} items Items that were not consumed.\n\t\t*/\n\t\tthrow new CKEditorError(\"conversion-model-consumable-not-consumed\", null, { items });\n\t}\n\t/**\n\t* Gets a unique symbol for the passed {@link module:engine/model/textproxy~ModelTextProxy} instance.\n\t* All `ModelTextProxy` instances that have same parent, same start index and same end index will get the same symbol.\n\t*\n\t* Used internally to correctly consume `ModelTextProxy` instances.\n\t*\n\t* @internal\n\t* @param textProxy `ModelTextProxy` instance to get a symbol for.\n\t* @returns Symbol representing all equal instances of `ModelTextProxy`.\n\t*/\n\t_getSymbolForTextProxy(textProxy) {\n\t\tlet symbol = null;\n\t\tconst startMap = this._textProxyRegistry.get(textProxy.startOffset);\n\t\tif (startMap) {\n\t\t\tconst endMap = startMap.get(textProxy.endOffset);\n\t\t\tif (endMap) symbol = endMap.get(textProxy.parent);\n\t\t}\n\t\tif (!symbol) symbol = this._addSymbolForTextProxy(textProxy);\n\t\treturn symbol;\n\t}\n\t/**\n\t* Adds a symbol for the given {@link module:engine/model/textproxy~ModelTextProxy} instance.\n\t*\n\t* Used internally to correctly consume `ModelTextProxy` instances.\n\t*\n\t* @param textProxy Text proxy instance.\n\t* @returns Symbol generated for given `ModelTextProxy`.\n\t*/\n\t_addSymbolForTextProxy(textProxy) {\n\t\tconst start = textProxy.startOffset;\n\t\tconst end = textProxy.endOffset;\n\t\tconst parent = textProxy.parent;\n\t\tconst symbol = Symbol(\"$textProxy:\" + textProxy.data);\n\t\tlet startMap;\n\t\tlet endMap;\n\t\tstartMap = this._textProxyRegistry.get(start);\n\t\tif (!startMap) {\n\t\t\tstartMap = /* @__PURE__ */ new Map();\n\t\t\tthis._textProxyRegistry.set(start, startMap);\n\t\t}\n\t\tendMap = startMap.get(end);\n\t\tif (!endMap) {\n\t\t\tendMap = /* @__PURE__ */ new Map();\n\t\t\tstartMap.set(end, endMap);\n\t\t}\n\t\tendMap.set(parent, symbol);\n\t\treturn symbol;\n\t}\n};\n/**\n* Returns a normalized consumable type name from the given string. A normalized consumable type name is a string that has\n* at most one colon, for example: `insert` or `addMarker:highlight`. If a string to normalize has more \"parts\" (more colons),\n* the further parts are dropped, for example: `addattribute:bold:$text` -> `addattributes:bold`.\n*\n* @param type Consumable type.\n* @returns Normalized consumable type.\n*/\nfunction _normalizeConsumableType(type) {\n\tconst parts = type.split(\":\");\n\tif (parts[0] == \"insert\") return parts[0];\n\tif (parts[0] == \"addMarker\" || parts[0] == \"removeMarker\") return type;\n\treturn parts.length > 1 ? parts[0] + \":\" + parts[1] : parts[0];\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Sorts markers so the downcast result is deterministic regardless of the order\n* markers were added to the marker collection.\n*\n* The sort key is the marker's range, ordered \"right-to-left\" through the document so that\n* a marker's opening boundary is processed *after* any markers nested inside it. This way\n* the outer marker wraps the inner ones at conversion time.\n*\n* Cases (positions shown as `0123456789`, sort result top-to-bottom):\n*\n* 1. Non-overlapping ranges — sorted by position, last range first:\n*\n* a: [--] → c, b, a\n* b: [--]\n* c: [--]\n*\n* 2. Adjacent ranges (end === start) — treated as non-overlapping:\n*\n* first: [---] → third, second, first\n* second: [---]\n* third: [---]\n*\n* 3. Nested ranges (same start, different ends) — inner first, outer last:\n*\n* shorter: [-] → shorter, longer\n* longer: [---]\n*\n* 4. Partially overlapping ranges — sorted by start position:\n*\n* earlier: [---] → later, earlier\n* later: [---]\n*\n* 5. Identical ranges — fall back to reverse name comparison:\n*\n* alpha: [---] → charlie, bravo, alpha\n* bravo: [---]\n* charlie: [---]\n*\n* @internal\n*/\nfunction compareMarkersForDowncast([name1, range1], [name2, range2]) {\n\tif (range1.end.compareWith(range2.start) !== \"after\") return 1;\n\telse if (range1.start.compareWith(range2.end) !== \"before\") return -1;\n\telse switch (range1.start.compareWith(range2.start)) {\n\t\tcase \"before\": return 1;\n\t\tcase \"after\": return -1;\n\t\tdefault: switch (range1.end.compareWith(range2.end)) {\n\t\t\tcase \"before\": return -1;\n\t\t\tcase \"after\": return 1;\n\t\t\tdefault: return name2.localeCompare(name1);\n\t\t}\n\t}\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/conversion/downcastdispatcher\n*/\nconst DowncastDispatcherBase = /* #__PURE__ */ EmitterMixin();\n/**\n* The downcast dispatcher is a central point of downcasting (conversion from the model to the view), which is a process of reacting\n* to changes in the model and firing a set of events. The callbacks listening to these events are called converters. The\n* converters' role is to convert the model changes to changes in view (for example, adding view nodes or\n* changing attributes on view elements).\n*\n* During the conversion process, downcast dispatcher fires events basing on the state of the model and prepares\n* data for these events. It is important to understand that the events are connected with the changes done on the model,\n* for example: \"a node has been inserted\" or \"an attribute has changed\". This is in contrary to upcasting (a view-to-model conversion)\n* where you convert the view state (view nodes) to a model tree.\n*\n* The events are prepared basing on a diff created by the {@link module:engine/model/differ~Differ Differ}, which buffers them\n* and then passes to the downcast dispatcher as a diff between the old model state and the new model state.\n*\n* Note that because the changes are converted, there is a need to have a mapping between the model structure and the view structure.\n* To map positions and elements during the downcast (a model-to-view conversion), use {@link module:engine/conversion/mapper~Mapper}.\n*\n* Downcast dispatcher fires the following events for model tree changes:\n*\n* * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`} &ndash;\n* If a range of nodes was inserted to the model tree.\n* * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove `remove`} &ndash;\n* If a range of nodes was removed from the model tree.\n* * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`} &ndash;\n* If an attribute was added, changed or removed from a model node.\n*\n* For {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`}\n* and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`},\n* the downcast dispatcher generates {@link module:engine/conversion/modelconsumable~ModelConsumable consumables}.\n* These are used to have control over which changes have already been consumed. It is useful when some converters\n* overwrite others or convert multiple changes (for example, it converts an insertion of an element and also converts that\n* element's attributes during the insertion).\n*\n* Additionally, downcast dispatcher fires events for {@link module:engine/model/markercollection~Marker marker} changes:\n*\n* * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker `addMarker`} &ndash; If a marker was added.\n* * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker `removeMarker`} &ndash; If a marker was\n* removed.\n*\n* Note that changing a marker is done through removing the marker from the old range and adding it to the new range,\n* so both of these events are fired.\n*\n* Finally, a downcast dispatcher also handles firing events for the {@link module:engine/model/selection model selection}\n* conversion:\n*\n* * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:selection `selection`}\n* &ndash; Converts the selection from the model to the view.\n* * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`}\n* &ndash; Fired for every selection attribute.\n* * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker `addMarker`}\n* &ndash; Fired for every marker that contains a selection.\n*\n* Unlike the model tree and the markers, the events for selection are not fired for changes but for a selection state.\n*\n* When providing custom listeners for a downcast dispatcher, remember to check whether a given change has not been\n* {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} yet.\n*\n* When providing custom listeners for a downcast dispatcher, keep in mind that you **should not** stop the event. If you stop it,\n* then the default converter at the `lowest` priority will not trigger the conversion of this node's attributes and child nodes.\n*\n* When providing custom listeners for a downcast dispatcher, remember to use the provided\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter view downcast writer} to apply changes to the view document.\n*\n* You can read more about conversion in the following guide:\n*\n* * {@glink framework/deep-dive/conversion/downcast Downcast conversion}\n*\n* An example of a custom converter for the downcast dispatcher:\n*\n* ```ts\n* // You will convert inserting a \"paragraph\" model element into the model.\n* downcastDispatcher.on( 'insert:paragraph', ( evt, data, conversionApi ) => {\n* \t// Remember to check whether the change has not been consumed yet and consume it.\n* \tif ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {\n* \t\treturn;\n* \t}\n*\n* \t// Translate the position in the model to a position in the view.\n* \tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n*\n* \t// Create a <p> element that will be inserted into the view at the `viewPosition`.\n* \tconst viewElement = conversionApi.writer.createContainerElement( 'p' );\n*\n* \t// Bind the newly created view element to the model element so positions will map accordingly in the future.\n* \tconversionApi.mapper.bindElements( data.item, viewElement );\n*\n* \t// Add the newly created view element to the view.\n* \tconversionApi.writer.insert( viewPosition, viewElement );\n* } );\n* ```\n*/\nvar DowncastDispatcher = class extends DowncastDispatcherBase {\n\t/**\n\t* A template for an interface passed by the dispatcher to the event callbacks.\n\t*\n\t* @internal\n\t*/\n\t_conversionApi;\n\t/**\n\t* A map of already fired events for a given `ModelConsumable`.\n\t*/\n\t_firedEventsMap;\n\t/**\n\t* Creates a downcast dispatcher instance.\n\t*\n\t* @see module:engine/conversion/downcastdispatcher~DowncastConversionApi\n\t*\n\t* @param conversionApi Additional properties for an interface that will be passed to events fired\n\t* by the downcast dispatcher.\n\t*/\n\tconstructor(conversionApi) {\n\t\tsuper();\n\t\tthis._conversionApi = {\n\t\t\tdispatcher: this,\n\t\t\t...conversionApi\n\t\t};\n\t\tthis._firedEventsMap = /* @__PURE__ */ new WeakMap();\n\t}\n\t/**\n\t* Converts changes buffered in the given {@link module:engine/model/differ~Differ model differ}\n\t* and fires conversion events based on it.\n\t*\n\t* @fires insert\n\t* @fires remove\n\t* @fires attribute\n\t* @fires addMarker\n\t* @fires removeMarker\n\t* @fires reduceChanges\n\t* @param differ The differ object with buffered changes.\n\t* @param markers Markers related to the model fragment to convert.\n\t* @param writer The view writer that should be used to modify the view document.\n\t*/\n\tconvertChanges(differ, markers, writer) {\n\t\tconst refreshedItems = differ.getRefreshedItems();\n\t\tconst conversionApi = this._createConversionApi(writer, refreshedItems);\n\t\tfor (const change of differ.getMarkersToRemove()) this._convertMarkerRemove(change.name, change.range, conversionApi);\n\t\tconst changes = this._reduceChanges(differ.getChanges(), refreshedItems);\n\t\tfor (const entry of changes) if (entry.type === \"insert\") this._convertInsert(ModelRange._createFromPositionAndShift(entry.position, entry.length), conversionApi);\n\t\telse if (entry.type === \"reinsert\") this._convertReinsert(ModelRange._createFromPositionAndShift(entry.position, entry.length), conversionApi);\n\t\telse if (entry.type === \"remove\") this._convertRemove(entry.position, entry.length, entry.name, conversionApi);\n\t\telse this._convertAttribute(entry.range, entry.attributeKey, entry.attributeOldValue, entry.attributeNewValue, conversionApi);\n\t\tconversionApi.mapper.flushDeferredBindings();\n\t\tfor (const markerName of conversionApi.mapper.flushUnboundMarkerNames()) {\n\t\t\tconst markerRange = markers.get(markerName).getRange();\n\t\t\tthis._convertMarkerRemove(markerName, markerRange, conversionApi);\n\t\t\tthis._convertMarkerAdd(markerName, markerRange, conversionApi);\n\t\t}\n\t\tconst markersToAdd = differ.getMarkersToAdd().sort((a, b) => compareMarkersForDowncast([a.name, a.range], [b.name, b.range]));\n\t\tfor (const change of markersToAdd) this._convertMarkerAdd(change.name, change.range, conversionApi);\n\t\tconversionApi.consumable.verifyAllConsumed(\"insert\");\n\t}\n\t/**\n\t* Starts a conversion of a model range and the provided markers.\n\t*\n\t* @fires insert\n\t* @fires attribute\n\t* @fires addMarker\n\t* @param range The inserted range.\n\t* @param markers The map of markers that should be down-casted.\n\t* @param writer The view writer that should be used to modify the view document.\n\t* @param options Optional options object passed to `convertionApi.options`.\n\t*/\n\tconvert(range, markers, writer, options = {}) {\n\t\tconst conversionApi = this._createConversionApi(writer, void 0, options);\n\t\tthis._convertInsert(range, conversionApi);\n\t\tfor (const [name, range] of Array.from(markers).sort(compareMarkersForDowncast)) this._convertMarkerAdd(name, range, conversionApi);\n\t\tconversionApi.consumable.verifyAllConsumed(\"insert\");\n\t}\n\t/**\n\t* Starts the model selection conversion.\n\t*\n\t* Fires events for a given {@link module:engine/model/selection~ModelSelection selection} to start the selection conversion.\n\t*\n\t* @fires selection\n\t* @fires addMarker\n\t* @fires attribute\n\t* @param selection The selection to convert.\n\t* @param markers Markers connected with the converted model.\n\t* @param writer View writer that should be used to modify the view document.\n\t*/\n\tconvertSelection(selection, markers, writer) {\n\t\tconst conversionApi = this._createConversionApi(writer);\n\t\tthis.fire(\"cleanSelection\", { selection }, conversionApi);\n\t\tconst modelRoot = selection.getFirstPosition().root;\n\t\tif (!conversionApi.mapper.toViewElement(modelRoot)) return;\n\t\tconst markersAtSelection = Array.from(markers.getMarkersAtPosition(selection.getFirstPosition()));\n\t\tthis._addConsumablesForSelection(conversionApi.consumable, selection, markersAtSelection);\n\t\tthis.fire(\"selection\", { selection }, conversionApi);\n\t\tif (!selection.isCollapsed) return;\n\t\tfor (const marker of markersAtSelection) if (conversionApi.consumable.test(selection, \"addMarker:\" + marker.name)) {\n\t\t\tconst markerRange = marker.getRange();\n\t\t\tif (!shouldMarkerChangeBeConverted(selection.getFirstPosition(), marker, conversionApi.mapper)) continue;\n\t\t\tconst data = {\n\t\t\t\titem: selection,\n\t\t\t\tmarkerName: marker.name,\n\t\t\t\tmarkerRange\n\t\t\t};\n\t\t\tthis.fire(`addMarker:${marker.name}`, data, conversionApi);\n\t\t}\n\t\tfor (const key of selection.getAttributeKeys()) if (conversionApi.consumable.test(selection, \"attribute:\" + key)) {\n\t\t\tconst data = {\n\t\t\t\titem: selection,\n\t\t\t\trange: selection.getFirstRange(),\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: null,\n\t\t\t\tattributeNewValue: selection.getAttribute(key)\n\t\t\t};\n\t\t\tthis.fire(`attribute:${key}:$text`, data, conversionApi);\n\t\t}\n\t}\n\t/**\n\t* Fires insertion conversion of a range of nodes.\n\t*\n\t* For each node in the range, {@link #event:insert `insert` event is fired}. For each attribute on each node,\n\t* {@link #event:attribute `attribute` event is fired}.\n\t*\n\t* @fires insert\n\t* @fires attribute\n\t* @param range The inserted range.\n\t* @param conversionApi The conversion API object.\n\t* @param options.doNotAddConsumables Whether the ModelConsumable should not get populated\n\t* for items in the provided range.\n\t*/\n\t_convertInsert(range, conversionApi, options = {}) {\n\t\tif (!options.doNotAddConsumables) this._addConsumablesForInsert(conversionApi.consumable, range);\n\t\tfor (const data of range.getWalker({ shallow: true })) this._testAndFire(\"insert\", walkerValueToEventData(data), conversionApi);\n\t}\n\t/**\n\t* Fires conversion of a single node removal. Fires {@link #event:remove remove event} with provided data.\n\t*\n\t* @param position Position from which node was removed.\n\t* @param length Offset size of removed node.\n\t* @param name Name of removed node.\n\t* @param conversionApi The conversion API object.\n\t*/\n\t_convertRemove(position, length, name, conversionApi) {\n\t\tthis.fire(`remove:${name}`, {\n\t\t\tposition,\n\t\t\tlength\n\t\t}, conversionApi);\n\t}\n\t/**\n\t* Starts a conversion of an attribute change on a given `range`.\n\t*\n\t* For each node in the given `range`, {@link #event:attribute attribute event} is fired with the passed data.\n\t*\n\t* @fires attribute\n\t* @param range Changed range.\n\t* @param key Key of the attribute that has changed.\n\t* @param oldValue Attribute value before the change or `null` if the attribute has not been set before.\n\t* @param newValue New attribute value or `null` if the attribute has been removed.\n\t* @param conversionApi The conversion API object.\n\t*/\n\t_convertAttribute(range, key, oldValue, newValue, conversionApi) {\n\t\tthis._addConsumablesForRange(conversionApi.consumable, range, `attribute:${key}`);\n\t\tfor (const value of range) {\n\t\t\tconst data = {\n\t\t\t\titem: value.item,\n\t\t\t\trange: ModelRange._createFromPositionAndShift(value.previousPosition, value.length),\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\tattributeNewValue: newValue\n\t\t\t};\n\t\t\tthis._testAndFire(`attribute:${key}`, data, conversionApi);\n\t\t}\n\t}\n\t/**\n\t* Fires re-insertion conversion (with a `reconversion` flag passed to `remove` and `insert` events)\n\t* of a range of elements (only elements on the range depth, without children).\n\t*\n\t* For each node in the range on its depth (without children), {@link #event:insert `insert` event} is fired.\n\t* For each attribute on each node, {@link #event:attribute `attribute` event} is fired.\n\t*\n\t* @fires insert\n\t* @fires attribute\n\t* @param range The range to reinsert.\n\t* @param conversionApi The conversion API object.\n\t*/\n\t_convertReinsert(range, conversionApi) {\n\t\tconst walkerValues = Array.from(range.getWalker({ shallow: true }));\n\t\tthis._addConsumablesForInsert(conversionApi.consumable, walkerValues);\n\t\tfor (const data of walkerValues.map(walkerValueToEventData)) {\n\t\t\tthis.fire(`remove:${data.item.is(\"element\") ? data.item.name : \"$text\"}`, {\n\t\t\t\tposition: data.range.start,\n\t\t\t\tlength: data.item.offsetSize,\n\t\t\t\treconversion: true\n\t\t\t}, conversionApi);\n\t\t\tthis._testAndFire(\"insert\", {\n\t\t\t\t...data,\n\t\t\t\treconversion: true\n\t\t\t}, conversionApi);\n\t\t}\n\t}\n\t/**\n\t* Converts the added marker. Fires the {@link #event:addMarker `addMarker`} event for each item\n\t* in the marker's range. If the range is collapsed, a single event is dispatched. See the event description for more details.\n\t*\n\t* @fires addMarker\n\t* @param markerName Marker name.\n\t* @param markerRange The marker range.\n\t* @param conversionApi The conversion API object.\n\t*/\n\t_convertMarkerAdd(markerName, markerRange, conversionApi) {\n\t\tif (markerRange.root.rootName == \"$graveyard\") return;\n\t\tconst eventName = `addMarker:${markerName}`;\n\t\tconversionApi.consumable.add(markerRange, eventName);\n\t\tthis.fire(eventName, {\n\t\t\tmarkerName,\n\t\t\tmarkerRange\n\t\t}, conversionApi);\n\t\tif (!conversionApi.consumable.consume(markerRange, eventName)) return;\n\t\tthis._addConsumablesForRange(conversionApi.consumable, markerRange, eventName);\n\t\tfor (const item of markerRange.getItems()) {\n\t\t\tif (!conversionApi.consumable.test(item, eventName)) continue;\n\t\t\tconst data = {\n\t\t\t\titem,\n\t\t\t\trange: ModelRange._createOn(item),\n\t\t\t\tmarkerName,\n\t\t\t\tmarkerRange\n\t\t\t};\n\t\t\tthis.fire(eventName, data, conversionApi);\n\t\t}\n\t}\n\t/**\n\t* Fires the conversion of the marker removal. Fires the {@link #event:removeMarker `removeMarker`} event with the provided data.\n\t*\n\t* @fires removeMarker\n\t* @param markerName Marker name.\n\t* @param markerRange The marker range.\n\t* @param conversionApi The conversion API object.\n\t*/\n\t_convertMarkerRemove(markerName, markerRange, conversionApi) {\n\t\tif (markerRange.root.rootName == \"$graveyard\") return;\n\t\tthis.fire(`removeMarker:${markerName}`, {\n\t\t\tmarkerName,\n\t\t\tmarkerRange\n\t\t}, conversionApi);\n\t}\n\t/**\n\t* Fires the reduction of changes buffered in the {@link module:engine/model/differ~Differ `Differ`}.\n\t*\n\t* Features can replace selected {@link module:engine/model/differ~DifferItem `DifferItem`}s with `reinsert` entries to trigger\n\t* reconversion. The {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n\t* `DowncastHelpers.elementToStructure()`} is using this event to trigger reconversion.\n\t*\n\t* @fires reduceChanges\n\t*/\n\t_reduceChanges(changes, refreshedItems) {\n\t\tconst data = {\n\t\t\tchanges,\n\t\t\trefreshedItems\n\t\t};\n\t\tthis.fire(\"reduceChanges\", data);\n\t\treturn data.changes;\n\t}\n\t/**\n\t* Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume from a given range,\n\t* assuming that the range has just been inserted to the model.\n\t*\n\t* @param consumable The consumable.\n\t* @param walkerValues The walker values for the inserted range.\n\t* @returns The values to consume.\n\t*/\n\t_addConsumablesForInsert(consumable, walkerValues) {\n\t\tfor (const value of walkerValues) {\n\t\t\tconst item = value.item;\n\t\t\tif (consumable.test(item, \"insert\") === null) {\n\t\t\t\tconsumable.add(item, \"insert\");\n\t\t\t\tfor (const key of item.getAttributeKeys()) consumable.add(item, \"attribute:\" + key);\n\t\t\t}\n\t\t}\n\t\treturn consumable;\n\t}\n\t/**\n\t* Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume for a given range.\n\t*\n\t* @param consumable The consumable.\n\t* @param range The affected range.\n\t* @param type Consumable type.\n\t* @returns The values to consume.\n\t*/\n\t_addConsumablesForRange(consumable, range, type) {\n\t\tfor (const item of range.getItems()) consumable.add(item, type);\n\t\treturn consumable;\n\t}\n\t/**\n\t* Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with selection consumable values.\n\t*\n\t* @param consumable The consumable.\n\t* @param selection The selection to create the consumable from.\n\t* @param markers Markers that contain the selection.\n\t* @returns The values to consume.\n\t*/\n\t_addConsumablesForSelection(consumable, selection, markers) {\n\t\tconsumable.add(selection, \"selection\");\n\t\tfor (const marker of markers) consumable.add(selection, \"addMarker:\" + marker.name);\n\t\tfor (const key of selection.getAttributeKeys()) consumable.add(selection, \"attribute:\" + key);\n\t\treturn consumable;\n\t}\n\t/**\n\t* Tests whether given event wasn't already fired and if so, fires it.\n\t*\n\t* @fires insert\n\t* @fires attribute\n\t* @param type Event type.\n\t* @param data Event data.\n\t* @param conversionApi The conversion API object.\n\t*/\n\t_testAndFire(type, data, conversionApi) {\n\t\tconst eventName = getEventName(type, data);\n\t\tconst itemKey = data.item.is(\"$textProxy\") ? conversionApi.consumable._getSymbolForTextProxy(data.item) : data.item;\n\t\tconst eventsFiredForConversion = this._firedEventsMap.get(conversionApi);\n\t\tconst eventsFiredForItem = eventsFiredForConversion.get(itemKey);\n\t\tif (!eventsFiredForItem) eventsFiredForConversion.set(itemKey, /* @__PURE__ */ new Set([eventName]));\n\t\telse if (!eventsFiredForItem.has(eventName)) eventsFiredForItem.add(eventName);\n\t\telse return;\n\t\tthis.fire(eventName, data, conversionApi);\n\t}\n\t/**\n\t* Fires not already fired events for setting attributes on just inserted item.\n\t*\n\t* @param item The model item to convert attributes for.\n\t* @param conversionApi The conversion API object.\n\t*/\n\t_testAndFireAddAttributes(item, conversionApi) {\n\t\tconst data = {\n\t\t\titem,\n\t\t\trange: ModelRange._createOn(item)\n\t\t};\n\t\tfor (const key of data.item.getAttributeKeys()) {\n\t\t\tdata.attributeKey = key;\n\t\t\tdata.attributeOldValue = null;\n\t\t\tdata.attributeNewValue = data.item.getAttribute(key);\n\t\t\tthis._testAndFire(`attribute:${key}`, data, conversionApi);\n\t\t}\n\t}\n\t/**\n\t* Builds an instance of the {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi} from a template and a given\n\t* {@link module:engine/view/downcastwriter~ViewDowncastWriter `ViewDowncastWriter`} and options object.\n\t*\n\t* @param writer View writer that should be used to modify the view document.\n\t* @param refreshedItems A set of model elements that should not reuse their\n\t* previous view representations.\n\t* @param options Optional options passed to `convertionApi.options`.\n\t* @return The conversion API object.\n\t*/\n\t_createConversionApi(writer, refreshedItems = /* @__PURE__ */ new Set(), options = {}) {\n\t\tconst conversionApi = {\n\t\t\t...this._conversionApi,\n\t\t\tconsumable: new ModelConsumable(),\n\t\t\twriter,\n\t\t\toptions,\n\t\t\tconvertItem: (item) => this._convertInsert(ModelRange._createOn(item), conversionApi),\n\t\t\tconvertChildren: (element) => this._convertInsert(ModelRange._createIn(element), conversionApi, { doNotAddConsumables: true }),\n\t\t\tconvertAttributes: (item) => this._testAndFireAddAttributes(item, conversionApi),\n\t\t\tcanReuseView: (viewElement) => !refreshedItems.has(conversionApi.mapper.toModelElement(viewElement))\n\t\t};\n\t\tthis._firedEventsMap.set(conversionApi, /* @__PURE__ */ new Map());\n\t\treturn conversionApi;\n\t}\n};\n/**\n* Helper function, checks whether change of `marker` at `modelPosition` should be converted. Marker changes are not\n* converted if they happen inside an element with custom conversion method.\n*/\nfunction shouldMarkerChangeBeConverted(modelPosition, marker, mapper) {\n\tconst range = marker.getRange();\n\tconst ancestors = Array.from(modelPosition.getAncestors());\n\tancestors.shift();\n\tancestors.reverse();\n\treturn !ancestors.some((element) => {\n\t\tif (range.containsItem(element)) return !!mapper.toViewElement(element).getCustomProperty(\"addHighlight\");\n\t});\n}\nfunction getEventName(type, data) {\n\treturn `${type}:${data.item.is(\"element\") ? data.item.name : \"$text\"}`;\n}\nfunction walkerValueToEventData(value) {\n\treturn {\n\t\titem: value.item,\n\t\trange: ModelRange._createFromPositionAndShift(value.previousPosition, value.length)\n\t};\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/node\n*/\n/**\n* Model node. Most basic structure of model tree.\n*\n* This is an abstract class that is a base for other classes representing different nodes in model.\n*\n* **Note:** If a node is detached from the model tree, you can manipulate it using it's API.\n* However, it is **very important** that nodes already attached to model tree should be only changed through\n* {@link module:engine/model/writer~ModelWriter Writer API}.\n*\n* Changes done by `Node` methods, like {@link module:engine/model/element~ModelElement#_insertChild _insertChild} or\n* {@link module:engine/model/node~ModelNode#_setAttribute _setAttribute}\n* do not generate {@link module:engine/model/operation/operation~Operation operations}\n* which are essential for correct editor work if you modify nodes in {@link module:engine/model/document~ModelDocument document} root.\n*\n* The flow of working on `Node` (and classes that inherits from it) is as such:\n* 1. You can create a `Node` instance, modify it using it's API.\n* 2. Add `Node` to the model using `Batch` API.\n* 3. Change `Node` that was already added to the model using `Batch` API.\n*\n* Similarly, you cannot use `Batch` API on a node that has not been added to the model tree, with the exception\n* of {@link module:engine/model/writer~ModelWriter#insert inserting} that node to the model tree.\n*\n* Be aware that using {@link module:engine/model/writer~ModelWriter#remove remove from Batch API} does not allow to use `Node` API because\n* the information about `Node` is still kept in model document.\n*\n* In case of {@link module:engine/model/element~ModelElement element node}, adding and removing children also counts as changing a node and\n* follows same rules.\n*/\nvar ModelNode = class extends ModelTypeCheckable {\n\t/**\n\t* Parent of this node. It could be {@link module:engine/model/element~ModelElement}\n\t* or {@link module:engine/model/documentfragment~ModelDocumentFragment}.\n\t* Equals to `null` if the node has no parent.\n\t*/\n\tparent = null;\n\t/**\n\t* Attributes set on this node.\n\t*/\n\t_attrs;\n\t/**\n\t* Index of this node in its parent or `null` if the node has no parent.\n\t*\n\t* @internal\n\t*/\n\t_index = null;\n\t/**\n\t* Offset at which this node starts in its parent or `null` if the node has no parent.\n\t*\n\t* @internal\n\t*/\n\t_startOffset = null;\n\t/**\n\t* Creates a model node.\n\t*\n\t* This is an abstract class, so this constructor should not be used directly.\n\t*\n\t* @param attrs Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t*/\n\tconstructor(attrs) {\n\t\tsuper();\n\t\tthis._attrs = toMap(attrs);\n\t}\n\t/**\n\t* {@link module:engine/model/document~ModelDocument Document} that owns this root element.\n\t*/\n\tget document() {\n\t\treturn null;\n\t}\n\t/**\n\t* Index of this node in its parent or `null` if the node has no parent.\n\t*/\n\tget index() {\n\t\treturn this._index;\n\t}\n\t/**\n\t* Offset at which this node starts in its parent. It is equal to the sum of {@link #offsetSize offsetSize}\n\t* of all its previous siblings. Equals to `null` if node has no parent.\n\t*/\n\tget startOffset() {\n\t\treturn this._startOffset;\n\t}\n\t/**\n\t* Offset size of this node.\n\t*\n\t* Represents how much \"offset space\" is occupied by the node in its parent. It is important for\n\t* {@link module:engine/model/position~ModelPosition position}. When node has `offsetSize` greater\n\t* than `1`, position can be placed between that node start and end. `offsetSize` greater than `1` is for\n\t* nodes that represents more than one entity, i.e. a {@link module:engine/model/text~ModelText text node}.\n\t*/\n\tget offsetSize() {\n\t\treturn 1;\n\t}\n\t/**\n\t* Offset at which this node ends in its parent. It is equal to the sum of this node's\n\t* {@link module:engine/model/node~ModelNode#startOffset start offset} and {@link #offsetSize offset size}.\n\t* Equals to `null` if the node has no parent.\n\t*/\n\tget endOffset() {\n\t\tif (this.startOffset === null) return null;\n\t\treturn this.startOffset + this.offsetSize;\n\t}\n\t/**\n\t* Node's next sibling or `null` if the node is a last child of it's parent or if the node has no parent.\n\t*/\n\tget nextSibling() {\n\t\tconst index = this.index;\n\t\treturn index !== null && this.parent.getChild(index + 1) || null;\n\t}\n\t/**\n\t* Node's previous sibling or `null` if the node is a first child of it's parent or if the node has no parent.\n\t*/\n\tget previousSibling() {\n\t\tconst index = this.index;\n\t\treturn index !== null && this.parent.getChild(index - 1) || null;\n\t}\n\t/**\n\t* The top-most ancestor of the node. If node has no parent it is the root itself. If the node is a part\n\t* of {@link module:engine/model/documentfragment~ModelDocumentFragment}, it's `root` is equal to that `DocumentFragment`.\n\t*/\n\tget root() {\n\t\tlet root = this;\n\t\twhile (root.parent) root = root.parent;\n\t\treturn root;\n\t}\n\t/**\n\t* Returns `true` if the node is inside a document root that is attached to the document.\n\t*/\n\tisAttached() {\n\t\treturn this.parent === null ? false : this.root.isAttached();\n\t}\n\t/**\n\t* Gets path to the node. The path is an array containing starting offsets of consecutive ancestors of this node,\n\t* beginning from {@link module:engine/model/node~ModelNode#root root}, down to this node's starting offset. The path can be used to\n\t* create {@link module:engine/model/position~ModelPosition Position} instance.\n\t*\n\t* ```ts\n\t* const abc = new Text( 'abc' );\n\t* const foo = new Text( 'foo' );\n\t* const h1 = new ModelElement( 'h1', null, new Text( 'header' ) );\n\t* const p = new ModelElement( 'p', null, [ abc, foo ] );\n\t* const div = new ModelElement( 'div', null, [ h1, p ] );\n\t* foo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t* h1.getPath(); // Returns [ 0 ].\n\t* div.getPath(); // Returns [].\n\t* ```\n\t*/\n\tgetPath() {\n\t\tconst path = [];\n\t\tlet node = this;\n\t\twhile (node.parent) {\n\t\t\tpath.unshift(node.startOffset);\n\t\t\tnode = node.parent;\n\t\t}\n\t\treturn path;\n\t}\n\t/**\n\t* Returns ancestors array of this node.\n\t*\n\t* @param options Options object.\n\t* @param options.includeSelf When set to `true` this node will be also included in parent's array.\n\t* @param options.parentFirst When set to `true`, array will be sorted from node's parent to root element,\n\t* otherwise root element will be the first item in the array.\n\t* @returns Array with ancestors.\n\t*/\n\tgetAncestors(options = {}) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\t\twhile (parent) {\n\t\t\tancestors[options.parentFirst ? \"push\" : \"unshift\"](parent);\n\t\t\tparent = parent.parent;\n\t\t}\n\t\treturn ancestors;\n\t}\n\t/**\n\t* Returns a {@link module:engine/model/element~ModelElement} or {@link module:engine/model/documentfragment~ModelDocumentFragment}\n\t* which is a common ancestor of both nodes.\n\t*\n\t* @param node The second node.\n\t* @param options Options object.\n\t* @param options.includeSelf When set to `true` both nodes will be considered \"ancestors\" too.\n\t* Which means that if e.g. node A is inside B, then their common ancestor will be B.\n\t*/\n\tgetCommonAncestor(node, options = {}) {\n\t\tconst ancestorsA = this.getAncestors(options);\n\t\tconst ancestorsB = node.getAncestors(options);\n\t\tlet i = 0;\n\t\twhile (ancestorsA[i] == ancestorsB[i] && ancestorsA[i]) i++;\n\t\treturn i === 0 ? null : ancestorsA[i - 1];\n\t}\n\t/**\n\t* Returns whether this node is before given node. `false` is returned if nodes are in different trees (for example,\n\t* in different {@link module:engine/model/documentfragment~ModelDocumentFragment}s).\n\t*\n\t* @param node Node to compare with.\n\t*/\n\tisBefore(node) {\n\t\tif (this == node) return false;\n\t\tif (this.root !== node.root) return false;\n\t\tconst thisPath = this.getPath();\n\t\tconst nodePath = node.getPath();\n\t\tconst result = compareArrays(thisPath, nodePath);\n\t\tswitch (result) {\n\t\t\tcase \"prefix\": return true;\n\t\t\tcase \"extension\": return false;\n\t\t\tdefault: return thisPath[result] < nodePath[result];\n\t\t}\n\t}\n\t/**\n\t* Returns whether this node is after given node. `false` is returned if nodes are in different trees (for example,\n\t* in different {@link module:engine/model/documentfragment~ModelDocumentFragment}s).\n\t*\n\t* @param node Node to compare with.\n\t*/\n\tisAfter(node) {\n\t\tif (this == node) return false;\n\t\tif (this.root !== node.root) return false;\n\t\treturn !this.isBefore(node);\n\t}\n\t/**\n\t* Checks if the node has an attribute with given key.\n\t*\n\t* @param key Key of attribute to check.\n\t* @returns `true` if attribute with given key is set on node, `false` otherwise.\n\t*/\n\thasAttribute(key) {\n\t\treturn this._attrs.has(key);\n\t}\n\t/**\n\t* Gets an attribute value for given key or `undefined` if that attribute is not set on node.\n\t*\n\t* @param key Key of attribute to look for.\n\t* @returns Attribute value or `undefined`.\n\t*/\n\tgetAttribute(key) {\n\t\treturn this._attrs.get(key);\n\t}\n\t/**\n\t* Returns iterator that iterates over this node's attributes.\n\t*\n\t* Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t* This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t*/\n\tgetAttributes() {\n\t\treturn this._attrs.entries();\n\t}\n\t/**\n\t* Returns iterator that iterates over this node's attribute keys.\n\t*/\n\tgetAttributeKeys() {\n\t\treturn this._attrs.keys();\n\t}\n\t/**\n\t* Converts `Node` to plain object and returns it.\n\t*\n\t* @returns `Node` converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = {};\n\t\tif (this._attrs.size) json.attributes = Array.from(this._attrs).reduce((result, attr) => {\n\t\t\tresult[attr[0]] = attr[1];\n\t\t\treturn result;\n\t\t}, {});\n\t\treturn json;\n\t}\n\t/**\n\t* Creates a copy of this node, that is a node with exactly same attributes, and returns it.\n\t*\n\t* @internal\n\t* @returns Node with same attributes as this node.\n\t*/\n\t_clone(_deep) {\n\t\treturn new this.constructor(this._attrs);\n\t}\n\t/**\n\t* Removes this node from its parent.\n\t*\n\t* @internal\n\t* @see module:engine/model/writer~ModelWriter#remove\n\t*/\n\t_remove() {\n\t\tthis.parent._removeChildren(this.index);\n\t}\n\t/**\n\t* Sets attribute on the node. If attribute with the same key already is set, it's value is overwritten.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#setAttribute\n\t* @internal\n\t* @param key Key of attribute to set.\n\t* @param value Attribute value.\n\t*/\n\t_setAttribute(key, value) {\n\t\tthis._attrs.set(key, value);\n\t}\n\t/**\n\t* Removes all attributes from the node and sets given attributes.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#setAttributes\n\t* @internal\n\t* @param attrs Attributes to set. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t*/\n\t_setAttributesTo(attrs) {\n\t\tthis._attrs = toMap(attrs);\n\t}\n\t/**\n\t* Removes an attribute with given key from the node.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#removeAttribute\n\t* @internal\n\t* @param key Key of attribute to remove.\n\t* @returns `true` if the attribute was set on the element, `false` otherwise.\n\t*/\n\t_removeAttribute(key) {\n\t\treturn this._attrs.delete(key);\n\t}\n\t/**\n\t* Removes all attributes from the node.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#clearAttributes\n\t* @internal\n\t*/\n\t_clearAttributes() {\n\t\tthis._attrs.clear();\n\t}\n};\nModelNode.prototype.is = function(type) {\n\treturn type === \"node\" || type === \"model:node\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/selection\n*/\nconst ModelSelectionBase = /* #__PURE__ */ EmitterMixin(ModelTypeCheckable);\n/**\n* Selection is a set of {@link module:engine/model/range~ModelRange ranges}. It has a direction specified by its\n* {@link module:engine/model/selection~ModelSelection#anchor anchor} and {@link module:engine/model/selection~ModelSelection#focus focus}\n* (it can be {@link module:engine/model/selection~ModelSelection#isBackward forward or backward}).\n* Additionally, selection may have its own attributes (think – whether text typed in in this selection\n* should have those attributes – e.g. whether you type a bolded text).\n*/\nvar ModelSelection = class ModelSelection extends ModelSelectionBase {\n\t/**\n\t* Specifies whether the last added range was added as a backward or forward range.\n\t*/\n\t_lastRangeBackward = false;\n\t/**\n\t* List of attributes set on current selection.\n\t*/\n\t_attrs = /* @__PURE__ */ new Map();\n\t/** @internal */\n\t_ranges = [];\n\t/**\n\t* Creates a new selection instance based on the given {@link module:engine/model/selection~ModelSelectable selectable}\n\t* or creates an empty selection if no arguments were passed.\n\t*\n\t* ```ts\n\t* // Creates empty selection without ranges.\n\t* const selection = writer.createSelection();\n\t*\n\t* // Creates selection at the given range.\n\t* const range = writer.createRange( start, end );\n\t* const selection = writer.createSelection( range );\n\t*\n\t* // Creates selection at the given ranges\n\t* const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t* const selection = writer.createSelection( ranges );\n\t*\n\t* // Creates selection from the other selection.\n\t* // Note: It doesn't copy selection attributes.\n\t* const otherSelection = writer.createSelection();\n\t* const selection = writer.createSelection( otherSelection );\n\t*\n\t* // Creates selection from the given document selection.\n\t* // Note: It doesn't copy selection attributes.\n\t* const documentSelection = model.document.selection;\n\t* const selection = writer.createSelection( documentSelection );\n\t*\n\t* // Creates selection at the given position.\n\t* const position = writer.createPositionFromPath( root, path );\n\t* const selection = writer.createSelection( position );\n\t*\n\t* // Creates selection at the given offset in the given element.\n\t* const paragraph = writer.createElement( 'paragraph' );\n\t* const selection = writer.createSelection( paragraph, offset );\n\t*\n\t* // Creates a range inside an {@link module:engine/model/element~ModelElement element} which starts before the\n\t* // first child of that element and ends after the last child of that element.\n\t* const selection = writer.createSelection( paragraph, 'in' );\n\t*\n\t* // Creates a range on an {@link module:engine/model/item~ModelItem item} which starts before the item and ends\n\t* // just after the item.\n\t* const selection = writer.createSelection( paragraph, 'on' );\n\t* ```\n\t*\n\t* Selection's constructor allow passing additional options (`'backward'`) as the last argument.\n\t*\n\t* ```ts\n\t* // Creates backward selection.\n\t* const selection = writer.createSelection( range, { backward: true } );\n\t* ```\n\t*\n\t* @internal\n\t*/\n\tconstructor(...args) {\n\t\tsuper();\n\t\tif (args.length) this.setTo(...args);\n\t}\n\t/**\n\t* Selection anchor. Anchor is the position from which the selection was started. If a user is making a selection\n\t* by dragging the mouse, the anchor is where the user pressed the mouse button (the beginning of the selection).\n\t*\n\t* Anchor and {@link #focus} define the direction of the selection, which is important\n\t* when expanding/shrinking selection. The focus moves, while the anchor should remain in the same place.\n\t*\n\t* Anchor is always set to the {@link module:engine/model/range~ModelRange#start start} or\n\t* {@link module:engine/model/range~ModelRange#end end} position of the last of selection's ranges. Whether it is\n\t* the `start` or `end` depends on the specified `options.backward`. See the {@link #setTo `setTo()`} method.\n\t*\n\t* May be set to `null` if there are no ranges in the selection.\n\t*\n\t* @see #focus\n\t*/\n\tget anchor() {\n\t\tif (this._ranges.length > 0) {\n\t\t\tconst range = this._ranges[this._ranges.length - 1];\n\t\t\treturn this._lastRangeBackward ? range.end : range.start;\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Selection focus. Focus is the position where the selection ends. If a user is making a selection\n\t* by dragging the mouse, the focus is where the mouse cursor is.\n\t*\n\t* May be set to `null` if there are no ranges in the selection.\n\t*\n\t* @see #anchor\n\t*/\n\tget focus() {\n\t\tif (this._ranges.length > 0) {\n\t\t\tconst range = this._ranges[this._ranges.length - 1];\n\t\t\treturn this._lastRangeBackward ? range.start : range.end;\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Whether the selection is collapsed. Selection is collapsed when there is exactly one range in it\n\t* and it is collapsed.\n\t*/\n\tget isCollapsed() {\n\t\tif (this._ranges.length === 1) return this._ranges[0].isCollapsed;\n\t\telse return false;\n\t}\n\t/**\n\t* Returns the number of ranges in the selection.\n\t*/\n\tget rangeCount() {\n\t\treturn this._ranges.length;\n\t}\n\t/**\n\t* Specifies whether the selection's {@link #focus} precedes the selection's {@link #anchor}.\n\t*/\n\tget isBackward() {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\t/**\n\t* Checks whether this selection is equal to the given selection. Selections are equal if they have the same directions,\n\t* the same number of ranges and all ranges from one selection equal to ranges from the another selection.\n\t*\n\t* @param otherSelection Selection to compare with.\n\t* @returns `true` if selections are equal, `false` otherwise.\n\t*/\n\tisEqual(otherSelection) {\n\t\tif (this.rangeCount != otherSelection.rangeCount) return false;\n\t\telse if (this.rangeCount === 0) return true;\n\t\tif (!this.anchor.isEqual(otherSelection.anchor) || !this.focus.isEqual(otherSelection.focus)) return false;\n\t\tfor (const thisRange of this._ranges) {\n\t\t\tlet found = false;\n\t\t\tfor (const otherRange of otherSelection._ranges) if (thisRange.isEqual(otherRange)) {\n\t\t\t\tfound = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!found) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Returns an iterable object that iterates over copies of selection ranges.\n\t*/\n\t*getRanges() {\n\t\tfor (const range of this._ranges) yield new ModelRange(range.start, range.end);\n\t}\n\t/**\n\t* Returns a copy of the first range in the selection.\n\t* First range is the one which {@link module:engine/model/range~ModelRange#start start} position\n\t* {@link module:engine/model/position~ModelPosition#isBefore is before} start position of all other ranges\n\t* (not to confuse with the first range added to the selection).\n\t*\n\t* Returns `null` if there are no ranges in selection.\n\t*/\n\tgetFirstRange() {\n\t\tlet first = null;\n\t\tfor (const range of this._ranges) if (!first || range.start.isBefore(first.start)) first = range;\n\t\treturn first ? new ModelRange(first.start, first.end) : null;\n\t}\n\t/**\n\t* Returns a copy of the last range in the selection.\n\t* Last range is the one which {@link module:engine/model/range~ModelRange#end end} position\n\t* {@link module:engine/model/position~ModelPosition#isAfter is after} end position of all other\n\t* ranges (not to confuse with the range most recently added to the selection).\n\t*\n\t* Returns `null` if there are no ranges in selection.\n\t*/\n\tgetLastRange() {\n\t\tlet last = null;\n\t\tfor (const range of this._ranges) if (!last || range.end.isAfter(last.end)) last = range;\n\t\treturn last ? new ModelRange(last.start, last.end) : null;\n\t}\n\t/**\n\t* Returns the first position in the selection.\n\t* First position is the position that {@link module:engine/model/position~ModelPosition#isBefore is before}\n\t* any other position in the selection.\n\t*\n\t* Returns `null` if there are no ranges in selection.\n\t*/\n\tgetFirstPosition() {\n\t\tconst first = this.getFirstRange();\n\t\treturn first ? first.start.clone() : null;\n\t}\n\t/**\n\t* Returns the last position in the selection.\n\t* Last position is the position that {@link module:engine/model/position~ModelPosition#isAfter is after}\n\t* any other position in the selection.\n\t*\n\t* Returns `null` if there are no ranges in selection.\n\t*/\n\tgetLastPosition() {\n\t\tconst lastRange = this.getLastRange();\n\t\treturn lastRange ? lastRange.end.clone() : null;\n\t}\n\t/**\n\t* Sets this selection's ranges and direction to the specified location based on the given\n\t* {@link module:engine/model/selection~ModelSelectable selectable}.\n\t*\n\t* ```ts\n\t* // Removes all selection's ranges.\n\t* selection.setTo( null );\n\t*\n\t* // Sets selection to the given range.\n\t* const range = writer.createRange( start, end );\n\t* selection.setTo( range );\n\t*\n\t* // Sets selection to given ranges.\n\t* const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t* selection.setTo( ranges );\n\t*\n\t* // Sets selection to other selection.\n\t* // Note: It doesn't copy selection attributes.\n\t* const otherSelection = writer.createSelection();\n\t* selection.setTo( otherSelection );\n\t*\n\t* // Sets selection to the given document selection.\n\t* // Note: It doesn't copy selection attributes.\n\t* const documentSelection = new ModelDocumentSelection( doc );\n\t* selection.setTo( documentSelection );\n\t*\n\t* // Sets collapsed selection at the given position.\n\t* const position = writer.createPositionFromPath( root, path );\n\t* selection.setTo( position );\n\t*\n\t* // Sets collapsed selection at the position of the given node and an offset.\n\t* selection.setTo( paragraph, offset );\n\t* ```\n\t*\n\t* Creates a range inside an {@link module:engine/model/element~ModelElement element} which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* ```ts\n\t* selection.setTo( paragraph, 'in' );\n\t* ```\n\t*\n\t* Creates a range on an {@link module:engine/model/item~ModelItem item} which starts before the item and ends just after the item.\n\t*\n\t* ```ts\n\t* selection.setTo( paragraph, 'on' );\n\t* ```\n\t*\n\t* `Selection#setTo()` method allows passing additional options (`backward`) as the last argument.\n\t*\n\t* ```ts\n\t* // Sets backward selection.\n\t* const selection = writer.createSelection( range, { backward: true } );\n\t* ```\n\t*/\n\tsetTo(...args) {\n\t\tlet [selectable, placeOrOffset, options] = args;\n\t\tif (typeof placeOrOffset == \"object\") {\n\t\t\toptions = placeOrOffset;\n\t\t\tplaceOrOffset = void 0;\n\t\t}\n\t\tif (selectable === null) this._setRanges([]);\n\t\telse if (selectable instanceof ModelSelection) this._setRanges(selectable.getRanges(), selectable.isBackward);\n\t\telse if (selectable && typeof selectable.getRanges == \"function\") this._setRanges(selectable.getRanges(), selectable.isBackward);\n\t\telse if (selectable instanceof ModelRange) this._setRanges([selectable], !!options && !!options.backward);\n\t\telse if (selectable instanceof ModelPosition) this._setRanges([new ModelRange(selectable)]);\n\t\telse if (selectable instanceof ModelNode) {\n\t\t\tconst backward = !!options && !!options.backward;\n\t\t\tlet range;\n\t\t\tif (placeOrOffset == \"in\") range = ModelRange._createIn(selectable);\n\t\t\telse if (placeOrOffset == \"on\") range = ModelRange._createOn(selectable);\n\t\t\telse if (placeOrOffset !== void 0) range = new ModelRange(ModelPosition._createAt(selectable, placeOrOffset));\n\t\t\telse\n /**\n\t\t\t* selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t*\n\t\t\t* @error model-selection-setto-required-second-parameter\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"model-selection-setto-required-second-parameter\", [this, selectable]);\n\t\t\tthis._setRanges([range], backward);\n\t\t} else if (isIterable(selectable)) this._setRanges(selectable, options && !!options.backward);\n\t\telse\n /**\n\t\t* Cannot set the selection to the given place.\n\t\t*\n\t\t* Invalid parameters were specified when setting the selection. Common issues:\n\t\t*\n\t\t* * A {@link module:engine/model/textproxy~ModelTextProxy} instance was passed instead of\n\t\t* a real {@link module:engine/model/text~ModelText}.\n\t\t* * View nodes were passed instead of model nodes.\n\t\t* * `null`/`undefined` was passed.\n\t\t*\n\t\t* @error model-selection-setto-not-selectable\n\t\t*/\n\t\tthrow new CKEditorError(\"model-selection-setto-not-selectable\", [this, selectable]);\n\t}\n\t/**\n\t* Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t* is treated like the last added range and is used to set {@link module:engine/model/selection~ModelSelection#anchor} and\n\t* {@link module:engine/model/selection~ModelSelection#focus}. Accepts a flag describing in which direction the selection is made.\n\t*\n\t* @fires change:range\n\t* @param newRanges Ranges to set.\n\t* @param isLastBackward Flag describing if last added range was selected forward - from start to end (`false`)\n\t* or backward - from end to start (`true`).\n\t*/\n\t_setRanges(newRanges, isLastBackward = false) {\n\t\tconst ranges = Array.from(newRanges);\n\t\tconst anyNewRange = ranges.some((newRange) => {\n\t\t\tif (!(newRange instanceof ModelRange))\n /**\n\t\t\t* Selection range set to an object that is not an instance of {@link module:engine/model/range~ModelRange}.\n\t\t\t*\n\t\t\t* Only {@link module:engine/model/range~ModelRange} instances can be used to set a selection.\n\t\t\t* Common mistakes leading to this error are:\n\t\t\t*\n\t\t\t* * using DOM `Range` object,\n\t\t\t* * incorrect CKEditor 5 installation with multiple `ckeditor5-engine` packages having different versions.\n\t\t\t*\n\t\t\t* @error model-selection-set-ranges-not-range\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"model-selection-set-ranges-not-range\", [this, newRanges]);\n\t\t\treturn this._ranges.every((oldRange) => {\n\t\t\t\treturn !oldRange.isEqual(newRange);\n\t\t\t});\n\t\t});\n\t\tif (ranges.length === this._ranges.length && !anyNewRange) return;\n\t\tthis._replaceAllRanges(ranges);\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\t\tthis.fire(\"change:range\", { directChange: true });\n\t}\n\t/**\n\t* Moves {@link module:engine/model/selection~ModelSelection#focus} to the specified location.\n\t*\n\t* The location can be specified in the same form as\n\t* {@link module:engine/model/writer~ModelWriter#createPositionAt writer.createPositionAt()} parameters.\n\t*\n\t* @fires change:range\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~ModelItem model item}.\n\t*/\n\tsetFocus(itemOrPosition, offset) {\n\t\tif (this.anchor === null)\n /**\n\t\t* Cannot set selection focus if there are no ranges in selection.\n\t\t*\n\t\t* @error model-selection-setfocus-no-ranges\n\t\t*/\n\t\tthrow new CKEditorError(\"model-selection-setfocus-no-ranges\", [this, itemOrPosition]);\n\t\tconst newFocus = ModelPosition._createAt(itemOrPosition, offset);\n\t\tif (newFocus.compareWith(this.focus) == \"same\") return;\n\t\tconst anchor = this.anchor;\n\t\tif (this._ranges.length) this._popRange();\n\t\tif (newFocus.compareWith(anchor) == \"before\") {\n\t\t\tthis._pushRange(new ModelRange(newFocus, anchor));\n\t\t\tthis._lastRangeBackward = true;\n\t\t} else {\n\t\t\tthis._pushRange(new ModelRange(anchor, newFocus));\n\t\t\tthis._lastRangeBackward = false;\n\t\t}\n\t\tthis.fire(\"change:range\", { directChange: true });\n\t}\n\t/**\n\t* Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.\n\t*\n\t* @param key Key of attribute to look for.\n\t* @returns Attribute value or `undefined`.\n\t*/\n\tgetAttribute(key) {\n\t\treturn this._attrs.get(key);\n\t}\n\t/**\n\t* Returns iterable that iterates over this selection's attributes.\n\t*\n\t* Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t* This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t*/\n\tgetAttributes() {\n\t\treturn this._attrs.entries();\n\t}\n\t/**\n\t* Returns iterable that iterates over this selection's attribute keys.\n\t*/\n\tgetAttributeKeys() {\n\t\treturn this._attrs.keys();\n\t}\n\t/**\n\t* Checks if the selection has an attribute for given key.\n\t*\n\t* @param key Key of attribute to check.\n\t* @returns `true` if attribute with given key is set on selection, `false` otherwise.\n\t*/\n\thasAttribute(key) {\n\t\treturn this._attrs.has(key);\n\t}\n\t/**\n\t* Removes an attribute with given key from the selection.\n\t*\n\t* If given attribute was set on the selection, fires the {@link #event:change:range} event with\n\t* removed attribute key.\n\t*\n\t* @fires change:attribute\n\t* @param key Key of attribute to remove.\n\t*/\n\tremoveAttribute(key) {\n\t\tif (this.hasAttribute(key)) {\n\t\t\tthis._attrs.delete(key);\n\t\t\tthis.fire(\"change:attribute\", {\n\t\t\t\tattributeKeys: [key],\n\t\t\t\tdirectChange: true\n\t\t\t});\n\t\t}\n\t}\n\t/**\n\t* Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t*\n\t* If the attribute value has changed, fires the {@link #event:change:range} event with\n\t* the attribute key.\n\t*\n\t* @fires change:attribute\n\t* @param key Key of attribute to set.\n\t* @param value Attribute value.\n\t*/\n\tsetAttribute(key, value) {\n\t\tif (this.getAttribute(key) !== value) {\n\t\t\tthis._attrs.set(key, value);\n\t\t\tthis.fire(\"change:attribute\", {\n\t\t\t\tattributeKeys: [key],\n\t\t\t\tdirectChange: true\n\t\t\t});\n\t\t}\n\t}\n\t/**\n\t* Returns the selected element. {@link module:engine/model/element~ModelElement Element} is considered as selected if there is only\n\t* one range in the selection, and that range contains exactly one element.\n\t* Returns `null` if there is no selected element.\n\t*/\n\tgetSelectedElement() {\n\t\tif (this.rangeCount !== 1) return null;\n\t\treturn this.getFirstRange().getContainedElement();\n\t}\n\t/**\n\t* Gets elements of type {@link module:engine/model/schema~ModelSchema#isBlock \"block\"} touched by the selection.\n\t*\n\t* This method's result can be used for example to apply block styling to all blocks covered by this selection.\n\t*\n\t* **Note:** `getSelectedBlocks()` returns blocks that are nested in other non-block elements\n\t* but will not return blocks nested in other blocks.\n\t*\n\t* In this case the function will return exactly all 3 paragraphs (note: `<blockQuote>` is not a block itself):\n\t*\n\t* ```xml\n\t* <paragraph>[a</paragraph>\n\t* <blockQuote>\n\t* \t<paragraph>b</paragraph>\n\t* </blockQuote>\n\t* <paragraph>c]d</paragraph>\n\t* ```\n\t*\n\t* In this case the paragraph will also be returned, despite the collapsed selection:\n\t*\n\t* ```xml\n\t* <paragraph>[]a</paragraph>\n\t* ```\n\t*\n\t* In such a scenario, however, only blocks A, B & E will be returned as blocks C & D are nested in block B:\n\t*\n\t* ```xml\n\t* [<blockA></blockA>\n\t* <blockB>\n\t* \t<blockC></blockC>\n\t* \t<blockD></blockD>\n\t* </blockB>\n\t* <blockE></blockE>]\n\t* ```\n\t*\n\t* If the selection is inside a block all the inner blocks (A & B) are returned:\n\t*\n\t* ```xml\n\t* <block>\n\t* \t<blockA>[a</blockA>\n\t* \t<blockB>b]</blockB>\n\t* </block>\n\t* ```\n\t*\n\t* **Special case**: Selection ignores first and/or last blocks if nothing (from user perspective) is selected in them.\n\t*\n\t* ```xml\n\t* // Selection ends and the beginning of the last block.\n\t* <paragraph>[a</paragraph>\n\t* <paragraph>b</paragraph>\n\t* <paragraph>]c</paragraph> // This block will not be returned\n\t*\n\t* // Selection begins at the end of the first block.\n\t* <paragraph>a[</paragraph> // This block will not be returned\n\t* <paragraph>b</paragraph>\n\t* <paragraph>c]</paragraph>\n\t*\n\t* // Selection begings at the end of the first block and ends at the beginning of the last block.\n\t* <paragraph>a[</paragraph> // This block will not be returned\n\t* <paragraph>b</paragraph>\n\t* <paragraph>]c</paragraph> // This block will not be returned\n\t* ```\n\t*/\n\t*getSelectedBlocks() {\n\t\tconst visited = /* @__PURE__ */ new WeakSet();\n\t\tfor (const range of this.getRanges()) {\n\t\t\tconst startBlock = getParentBlock$1(range.start, visited);\n\t\t\tif (isStartBlockSelected(startBlock, range)) yield startBlock;\n\t\t\tconst treewalker = range.getWalker();\n\t\t\tfor (const value of treewalker) {\n\t\t\t\tconst block = value.item;\n\t\t\t\tif (value.type == \"elementEnd\" && isUnvisitedTopBlock(block, visited, range)) yield block;\n\t\t\t\telse if (value.type == \"elementStart\" && block.is(\"model:element\") && block.root.document.model.schema.isBlock(block)) treewalker.jumpTo(ModelPosition._createAt(block, \"end\"));\n\t\t\t}\n\t\t\tconst endBlock = getParentBlock$1(range.end, visited);\n\t\t\tif (isEndBlockSelected(endBlock, range)) yield endBlock;\n\t\t}\n\t}\n\t/**\n\t* Checks whether the selection contains the entire content of the given element. This means that selection must start\n\t* at a position {@link module:engine/model/position~ModelPosition#isTouching touching} the element's start and ends at position\n\t* touching the element's end.\n\t*\n\t* By default, this method will check whether the entire content of the selection's current root is selected.\n\t* Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.\n\t*/\n\tcontainsEntireContent(element = this.anchor.root) {\n\t\tconst limitStartPosition = ModelPosition._createAt(element, 0);\n\t\tconst limitEndPosition = ModelPosition._createAt(element, \"end\");\n\t\treturn limitStartPosition.isTouching(this.getFirstPosition()) && limitEndPosition.isTouching(this.getLastPosition());\n\t}\n\t/**\n\t* Converts `Selection` to plain object and returns it.\n\t*\n\t* @returns `Selection` converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = { ranges: Array.from(this.getRanges()).map((range) => range.toJSON()) };\n\t\tconst attributes = Object.fromEntries(this.getAttributes());\n\t\tif (Object.keys(attributes).length) json.attributes = attributes;\n\t\tif (this.isBackward) json.isBackward = true;\n\t\treturn json;\n\t}\n\t/**\n\t* Adds given range to internal {@link #_ranges ranges array}. Throws an error\n\t* if given range is intersecting with any range that is already stored in this selection.\n\t*/\n\t_pushRange(range) {\n\t\tthis._checkRange(range);\n\t\tthis._ranges.push(new ModelRange(range.start, range.end));\n\t}\n\t/**\n\t* Checks if given range intersects with ranges that are already in the selection. Throws an error if it does.\n\t*/\n\t_checkRange(range) {\n\t\tfor (let i = 0; i < this._ranges.length; i++) if (range.isIntersecting(this._ranges[i]))\n /**\n\t\t* Trying to add a range that intersects with another range in the selection.\n\t\t*\n\t\t* @error model-selection-range-intersects\n\t\t* @param {module:engine/model/range~ModelRange} addedRange Range that was added to the selection.\n\t\t* @param {module:engine/model/range~ModelRange} intersectingRange Range in the selection that intersects with `addedRange`.\n\t\t*/\n\t\tthrow new CKEditorError(\"model-selection-range-intersects\", [this, range], {\n\t\t\taddedRange: range,\n\t\t\tintersectingRange: this._ranges[i]\n\t\t});\n\t}\n\t/**\n\t* Replaces all the ranges by the given ones.\n\t* Uses {@link #_popRange _popRange} and {@link #_pushRange _pushRange} to ensure proper ranges removal and addition.\n\t*/\n\t_replaceAllRanges(ranges) {\n\t\tthis._removeAllRanges();\n\t\tfor (const range of ranges) this._pushRange(range);\n\t}\n\t/**\n\t* Deletes ranges from internal range array. Uses {@link #_popRange _popRange} to\n\t* ensure proper ranges removal.\n\t*/\n\t_removeAllRanges() {\n\t\twhile (this._ranges.length > 0) this._popRange();\n\t}\n\t/**\n\t* Removes most recently added range from the selection.\n\t*/\n\t_popRange() {\n\t\tthis._ranges.pop();\n\t}\n};\nModelSelection.prototype.is = function(type) {\n\treturn type === \"selection\" || type === \"model:selection\";\n};\n/**\n* Checks whether the given element extends $block in the schema and has a parent (is not a root).\n* Marks it as already visited.\n*/\nfunction isUnvisitedBlock(element, visited) {\n\tif (visited.has(element)) return false;\n\tvisited.add(element);\n\treturn element.root.document.model.schema.isBlock(element) && !!element.parent;\n}\n/**\n* Checks if the given element is a $block was not previously visited and is a top block in a range.\n*/\nfunction isUnvisitedTopBlock(element, visited, range) {\n\treturn isUnvisitedBlock(element, visited) && isTopBlockInRange(element, range);\n}\n/**\n* Finds the lowest element in position's ancestors which is a block.\n* It will search until first ancestor that is a limit element.\n* Marks all ancestors as already visited to not include any of them later on.\n*/\nfunction getParentBlock$1(position, visited) {\n\tconst schema = position.parent.root.document.model.schema;\n\tconst ancestors = position.parent.getAncestors({\n\t\tparentFirst: true,\n\t\tincludeSelf: true\n\t});\n\tlet hasParentLimit = false;\n\tconst block = ancestors.find((element) => {\n\t\tif (hasParentLimit) return false;\n\t\thasParentLimit = schema.isLimit(element);\n\t\treturn !hasParentLimit && isUnvisitedBlock(element, visited);\n\t});\n\tancestors.forEach((element) => visited.add(element));\n\treturn block;\n}\n/**\n* Checks if the blocks is not nested in other block inside a range.\n*/\nfunction isTopBlockInRange(block, range) {\n\tconst parentBlock = findAncestorBlock(block);\n\tif (!parentBlock) return true;\n\treturn !range.containsRange(ModelRange._createOn(parentBlock), true);\n}\n/**\n* If a selection starts at the end of a block, that block is not returned as from the user's perspective this block wasn't selected.\n* See [#11585](https://github.com/ckeditor/ckeditor5/issues/11585) for more details.\n*\n* ```xml\n* <paragraph>a[</paragraph> // This block will not be returned\n* <paragraph>b</paragraph>\n* <paragraph>c]</paragraph>\n* ```\n*\n* Collapsed selection is not affected by it:\n*\n* ```xml\n* <paragraph>a[]</paragraph> // This block will be returned\n* ```\n*/\nfunction isStartBlockSelected(startBlock, range) {\n\tif (!startBlock) return false;\n\tif (range.isCollapsed || startBlock.isEmpty) return true;\n\tif (range.start.isTouching(ModelPosition._createAt(startBlock, startBlock.maxOffset))) return false;\n\treturn isTopBlockInRange(startBlock, range);\n}\n/**\n* If a selection ends at the beginning of a block, that block is not returned as from the user's perspective this block wasn't selected.\n* See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.\n*\n* ```xml\n* <paragraph>[a</paragraph>\n* <paragraph>b</paragraph>\n* <paragraph>]c</paragraph> // this block will not be returned\n* ```\n*\n* Collapsed selection is not affected by it:\n*\n* ```xml\n* <paragraph>[]a</paragraph> // this block will be returned\n* ```\n*/\nfunction isEndBlockSelected(endBlock, range) {\n\tif (!endBlock) return false;\n\tif (range.isCollapsed || endBlock.isEmpty) return true;\n\tif (range.end.isTouching(ModelPosition._createAt(endBlock, 0))) return false;\n\treturn isTopBlockInRange(endBlock, range);\n}\n/**\n* Returns first ancestor block of a node.\n*/\nfunction findAncestorBlock(node) {\n\tconst schema = node.root.document.model.schema;\n\tlet parent = node.parent;\n\twhile (parent) {\n\t\tif (schema.isBlock(parent)) return parent;\n\t\tparent = parent.parent;\n\t}\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/liverange\n*/\nconst ModelLiveRangeBase = /* #__PURE__ */ EmitterMixin(ModelRange);\n/**\n* `ModelLiveRange` is a type of {@link module:engine/model/range~ModelRange Range}\n* that updates itself as {@link module:engine/model/document~ModelDocument document}\n* is changed through operations. It may be used as a bookmark.\n*\n* **Note:** Be very careful when dealing with `ModelLiveRange`. Each `ModelLiveRange` instance bind events that might\n* have to be unbound. Use {@link module:engine/model/liverange~ModelLiveRange#detach detach} whenever you don't need\n* `ModelLiveRange` anymore.\n*/\nvar ModelLiveRange = class ModelLiveRange extends ModelLiveRangeBase {\n\t/**\n\t* Creates a live range.\n\t*\n\t* @see module:engine/model/range~ModelRange\n\t*/\n\tconstructor(start, end, model) {\n\t\tsuper(start, end);\n\t\tconst root = this.root;\n\t\tconst boundModel = model || (root.is(\"rootElement\") ? root.document.model : null);\n\t\tif (!boundModel)\n /**\n\t\t* LiveRange's root has to be an instance of ModelRootElement or have a reference to a model instance.\n\t\t*\n\t\t* @error model-liverange-no-model-reference\n\t\t*/\n\t\tthrow new CKEditorError(\"model-liverange-no-model-reference\", root);\n\t\tbindWithModel$1.call(this, boundModel);\n\t}\n\t/**\n\t* Unbinds all events previously bound by `ModelLiveRange`. Use it whenever you don't need `ModelLiveRange` instance\n\t* anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was\n\t* referring to it).\n\t*/\n\tdetach() {\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Creates a {@link module:engine/model/range~ModelRange range instance} that is equal to this live range.\n\t*/\n\ttoRange() {\n\t\treturn new ModelRange(this.start, this.end);\n\t}\n\t/**\n\t* Creates a `ModelLiveRange` instance that is equal to the given range.\n\t*/\n\tstatic fromRange(range) {\n\t\treturn new ModelLiveRange(range.start, range.end);\n\t}\n\t/**\n\t* Creates a `ModelLiveRange` for a range rooted in\n\t* a {@link module:engine/model/documentfragment~ModelDocumentFragment document fragment}.\n\t*\n\t* Document fragment does not belong to a document, so the live range is bound to the provided `model` and keeps\n\t* itself in sync with every operation applied to that fragment (e.g. while editing clipboard content).\n\t*\n\t* @internal\n\t*/\n\tstatic _fromRangeInDocumentFragment(range, model) {\n\t\treturn new this(range.start, range.end, model);\n\t}\n};\nModelLiveRange.prototype.is = function(type) {\n\treturn type === \"liveRange\" || type === \"model:liveRange\" || type == \"range\" || type === \"model:range\";\n};\n/**\n* Binds this `ModelLiveRange` to the given model, so the range updates itself on every operation applied to it.\n*/\nfunction bindWithModel$1(model) {\n\tconst isDetached = !this.root.is(\"rootElement\");\n\tthis.listenTo(model, \"applyOperation\", (event, args) => {\n\t\tconst operation = args[0];\n\t\tif (!isDetached && !operation.isDocumentOperation) return;\n\t\ttransform$2.call(this, operation);\n\t}, { priority: \"low\" });\n}\n/**\n* Updates this range accordingly to the updates applied to the model. Bases on change events.\n*/\nfunction transform$2(operation) {\n\tconst ranges = this.getTransformedByOperation(operation);\n\tif (ranges.length === 0) {\n\t\tconst deletionPosition = operation.sourcePosition;\n\t\tthis.start = deletionPosition;\n\t\tthis.end = deletionPosition;\n\t\tthis.fire(\"change:drop\", this.toRange(), { deletionPosition });\n\t\treturn;\n\t}\n\tconst result = ModelRange._createFromRanges(ranges);\n\tconst boundariesChanged = !result.isEqual(this);\n\tconst contentChanged = doesOperationChangeRangeContent(this, operation);\n\tlet deletionPosition = null;\n\tif (boundariesChanged) {\n\t\tif (result.root.rootName == \"$graveyard\") if (operation.type == \"remove\") deletionPosition = operation.sourcePosition;\n\t\telse deletionPosition = operation.deletionPosition;\n\t\tconst oldRange = this.toRange();\n\t\tthis.start = result.start;\n\t\tthis.end = result.end;\n\t\tthis.fire(\"change:range\", oldRange, { deletionPosition });\n\t} else if (contentChanged) this.fire(\"change:content\", this.toRange(), { deletionPosition });\n}\n/**\n* Checks whether given operation changes something inside the range (even if it does not change boundaries).\n*/\nfunction doesOperationChangeRangeContent(range, operation) {\n\tswitch (operation.type) {\n\t\tcase \"insert\": return range.containsPosition(operation.position);\n\t\tcase \"move\":\n\t\tcase \"remove\":\n\t\tcase \"reinsert\":\n\t\tcase \"merge\": return range.containsPosition(operation.sourcePosition) || range.start.isEqual(operation.sourcePosition) || range.containsPosition(operation.targetPosition);\n\t\tcase \"split\": return range.containsPosition(operation.splitPosition) || range.containsPosition(operation.insertionPosition);\n\t}\n\treturn false;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/text\n*/\n/**\n* Model text node. Type of {@link module:engine/model/node~ModelNode node} that\n* contains {@link module:engine/model/text~ModelText#data text data}.\n*\n* **Important:** see {@link module:engine/model/node~ModelNode} to read about restrictions using `Text` and `Node` API.\n*\n* **Note:** keep in mind that `Text` instances might indirectly got removed from model tree when model is changed.\n* This happens when {@link module:engine/model/writer~ModelWriter model writer} is used to change model and the text node is merged with\n* another text node. Then, both text nodes are removed and a new text node is inserted into the model. Because of\n* this behavior, keeping references to `Text` is not recommended. Instead, consider creating\n* {@link module:engine/model/liveposition~ModelLivePosition live position} placed before the text node.\n*/\nvar ModelText = class ModelText extends ModelNode {\n\t/**\n\t* Text data contained in this text node.\n\t*\n\t* @internal\n\t*/\n\t_data;\n\t/**\n\t* Creates a text node.\n\t*\n\t* **Note:** Constructor of this class shouldn't be used directly in the code.\n\t* Use the {@link module:engine/model/writer~ModelWriter#createText} method instead.\n\t*\n\t* @internal\n\t* @param data Node's text.\n\t* @param attrs Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t*/\n\tconstructor(data, attrs) {\n\t\tsuper(attrs);\n\t\tthis._data = data || \"\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget offsetSize() {\n\t\treturn this.data.length;\n\t}\n\t/**\n\t* Returns a text data contained in the node.\n\t*/\n\tget data() {\n\t\treturn this._data;\n\t}\n\t/**\n\t* Converts `Text` instance to plain object and returns it.\n\t*\n\t* @returns`Text` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.data = this.data;\n\t\treturn json;\n\t}\n\t/**\n\t* Creates a copy of this text node and returns it. Created text node has same text data and attributes as original text node.\n\t*\n\t* @internal\n\t* @returns `Text` instance created using given plain object.\n\t*/\n\t_clone() {\n\t\treturn new ModelText(this.data, this.getAttributes());\n\t}\n\t/**\n\t* Creates a `Text` instance from given plain object (i.e. parsed JSON string).\n\t*\n\t* @param json Plain object to be converted to `Text`.\n\t* @returns `Text` instance created using given plain object.\n\t*/\n\tstatic fromJSON(json) {\n\t\treturn new ModelText(json.data, json.attributes);\n\t}\n};\nModelText.prototype.is = function(type) {\n\treturn type === \"$text\" || type === \"model:$text\" || type === \"text\" || type === \"model:text\" || type === \"node\" || type === \"model:node\";\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/documentselection\n*/\nconst storePrefix = \"selection:\";\nconst ModelDocumentSelectionBase = /* #__PURE__ */ EmitterMixin(ModelTypeCheckable);\n/**\n* `ModelDocumentSelection` is a special selection which is used as the\n* {@link module:engine/model/document~ModelDocument#selection document's selection}.\n* There can be only one instance of `ModelDocumentSelection` per document.\n*\n* Document selection can only be changed by using the {@link module:engine/model/writer~ModelWriter} instance\n* inside the {@link module:engine/model/model~Model#change `change()`} block, as it provides a secure way to modify model.\n*\n* `ModelDocumentSelection` is automatically updated upon changes in the {@link module:engine/model/document~ModelDocument document}\n* to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.\n*\n* Differences between {@link module:engine/model/selection~ModelSelection} and `ModelDocumentSelection` are:\n* * there is always a range in `ModelDocumentSelection` - even if no ranges were added there is a \"default range\"\n* present in the selection,\n* * ranges added to this selection updates automatically when the document changes,\n* * attributes of `ModelDocumentSelection` are updated automatically according to selection ranges.\n*\n* Since `ModelDocumentSelection` uses {@link module:engine/model/liverange~ModelLiveRange live ranges}\n* and is updated when {@link module:engine/model/document~ModelDocument document}\n* changes, it cannot be set on {@link module:engine/model/node~ModelNode nodes}\n* that are inside {@link module:engine/model/documentfragment~ModelDocumentFragment document fragment}.\n* If you need to represent a selection in document fragment,\n* use {@link module:engine/model/selection~ModelSelection Selection class} instead.\n*/\nvar ModelDocumentSelection = class extends ModelDocumentSelectionBase {\n\t/**\n\t* Selection used internally by that class (`ModelDocumentSelection` is a proxy to that selection).\n\t*/\n\t_selection;\n\t/**\n\t* Creates an empty live selection for given {@link module:engine/model/document~ModelDocument}.\n\t*\n\t* @param doc Document which owns this selection.\n\t*/\n\tconstructor(doc) {\n\t\tsuper();\n\t\tthis._selection = new LiveSelection(doc);\n\t\tthis._selection.delegate(\"change:range\").to(this);\n\t\tthis._selection.delegate(\"change:attribute\").to(this);\n\t\tthis._selection.delegate(\"change:marker\").to(this);\n\t}\n\t/**\n\t* Describes whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t* collapsed.\n\t*/\n\tget isCollapsed() {\n\t\treturn this._selection.isCollapsed;\n\t}\n\t/**\n\t* Selection anchor. Anchor may be described as a position where the most recent part of the selection starts.\n\t* Together with {@link #focus} they define the direction of selection, which is important\n\t* when expanding/shrinking selection. Anchor is always {@link module:engine/model/range~ModelRange#start start} or\n\t* {@link module:engine/model/range~ModelRange#end end} position of the most recently added range.\n\t*\n\t* Is set to `null` if there are no ranges in selection.\n\t*\n\t* @see #focus\n\t*/\n\tget anchor() {\n\t\treturn this._selection.anchor;\n\t}\n\t/**\n\t* Selection focus. Focus is a position where the selection ends.\n\t*\n\t* Is set to `null` if there are no ranges in selection.\n\t*\n\t* @see #anchor\n\t*/\n\tget focus() {\n\t\treturn this._selection.focus;\n\t}\n\t/**\n\t* Number of ranges in selection.\n\t*/\n\tget rangeCount() {\n\t\treturn this._selection.rangeCount;\n\t}\n\t/**\n\t* Describes whether `Documentselection` has own range(s) set, or if it is defaulted to\n\t* {@link module:engine/model/document~ModelDocument#_getDefaultRange document's default range}.\n\t*/\n\tget hasOwnRange() {\n\t\treturn this._selection.hasOwnRange;\n\t}\n\t/**\n\t* Specifies whether the {@link #focus}\n\t* precedes {@link #anchor}.\n\t*\n\t* @readonly\n\t* @type {Boolean}\n\t*/\n\tget isBackward() {\n\t\treturn this._selection.isBackward;\n\t}\n\t/**\n\t* Describes whether the gravity is overridden (using {@link module:engine/model/writer~ModelWriter#overrideSelectionGravity}) or not.\n\t*\n\t* Note that the gravity remains overridden as long as will not be restored the same number of times as it was overridden.\n\t*/\n\tget isGravityOverridden() {\n\t\treturn this._selection.isGravityOverridden;\n\t}\n\t/**\n\t* A collection of selection {@link module:engine/model/markercollection~Marker markers}.\n\t* Marker is a selection marker when selection range is inside the marker range.\n\t*\n\t* **Note**: Only markers from {@link ~ModelDocumentSelection#observeMarkers observed markers groups} are collected.\n\t*/\n\tget markers() {\n\t\treturn this._selection.markers;\n\t}\n\t/**\n\t* Used for the compatibility with the {@link module:engine/model/selection~ModelSelection#isEqual} method.\n\t*\n\t* @internal\n\t*/\n\tget _ranges() {\n\t\treturn this._selection._ranges;\n\t}\n\t/**\n\t* Returns an iterable that iterates over copies of selection ranges.\n\t*/\n\tgetRanges() {\n\t\treturn this._selection.getRanges();\n\t}\n\t/**\n\t* Returns the first position in the selection.\n\t* First position is the position that {@link module:engine/model/position~ModelPosition#isBefore is before}\n\t* any other position in the selection.\n\t*\n\t* Returns `null` if there are no ranges in selection.\n\t*/\n\tgetFirstPosition() {\n\t\treturn this._selection.getFirstPosition();\n\t}\n\t/**\n\t* Returns the last position in the selection.\n\t* Last position is the position that {@link module:engine/model/position~ModelPosition#isAfter is after}\n\t* any other position in the selection.\n\t*\n\t* Returns `null` if there are no ranges in selection.\n\t*/\n\tgetLastPosition() {\n\t\treturn this._selection.getLastPosition();\n\t}\n\t/**\n\t* Returns a copy of the first range in the selection.\n\t* First range is the one which {@link module:engine/model/range~ModelRange#start start} position\n\t* {@link module:engine/model/position~ModelPosition#isBefore is before} start position of all other ranges\n\t* (not to confuse with the first range added to the selection).\n\t*\n\t* Returns `null` if there are no ranges in selection.\n\t*/\n\tgetFirstRange() {\n\t\treturn this._selection.getFirstRange();\n\t}\n\t/**\n\t* Returns a copy of the last range in the selection.\n\t* Last range is the one which {@link module:engine/model/range~ModelRange#end end} position\n\t* {@link module:engine/model/position~ModelPosition#isAfter is after} end position of all\n\t* other ranges (not to confuse with the range most recently added to the selection).\n\t*\n\t* Returns `null` if there are no ranges in selection.\n\t*/\n\tgetLastRange() {\n\t\treturn this._selection.getLastRange();\n\t}\n\t/**\n\t* Gets elements of type {@link module:engine/model/schema~ModelSchema#isBlock \"block\"} touched by the selection.\n\t*\n\t* This method's result can be used for example to apply block styling to all blocks covered by this selection.\n\t*\n\t* **Note:** `getSelectedBlocks()` returns blocks that are nested in other non-block elements\n\t* but will not return blocks nested in other blocks.\n\t*\n\t* In this case the function will return exactly all 3 paragraphs (note: `<blockQuote>` is not a block itself):\n\t*\n\t* ```\n\t* <paragraph>[a</paragraph>\n\t* <blockQuote>\n\t* \t<paragraph>b</paragraph>\n\t* </blockQuote>\n\t* <paragraph>c]d</paragraph>\n\t* ```\n\t*\n\t* In this case the paragraph will also be returned, despite the collapsed selection:\n\t*\n\t* ```\n\t* <paragraph>[]a</paragraph>\n\t* ```\n\t*\n\t* In such a scenario, however, only blocks A, B & E will be returned as blocks C & D are nested in block B:\n\t*\n\t* ```\n\t* [<blockA></blockA>\n\t* <blockB>\n\t* \t<blockC></blockC>\n\t* \t<blockD></blockD>\n\t* </blockB>\n\t* <blockE></blockE>]\n\t* ```\n\t*\n\t* If the selection is inside a block all the inner blocks (A & B) are returned:\n\t*\n\t* ```\n\t* <block>\n\t* \t<blockA>[a</blockA>\n\t* \t<blockB>b]</blockB>\n\t* </block>\n\t* ```\n\t*\n\t* **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective\n\t* this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.\n\t*\n\t* ```\n\t* <paragraph>[a</paragraph>\n\t* <paragraph>b</paragraph>\n\t* <paragraph>]c</paragraph> // this block will not be returned\n\t* ```\n\t*/\n\tgetSelectedBlocks() {\n\t\treturn this._selection.getSelectedBlocks();\n\t}\n\t/**\n\t* Returns the selected element. {@link module:engine/model/element~ModelElement Element} is considered as selected if there is only\n\t* one range in the selection, and that range contains exactly one element.\n\t* Returns `null` if there is no selected element.\n\t*/\n\tgetSelectedElement() {\n\t\treturn this._selection.getSelectedElement();\n\t}\n\t/**\n\t* Checks whether the selection contains the entire content of the given element. This means that selection must start\n\t* at a position {@link module:engine/model/position~ModelPosition#isTouching touching} the element's start and ends at position\n\t* touching the element's end.\n\t*\n\t* By default, this method will check whether the entire content of the selection's current root is selected.\n\t* Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.\n\t*/\n\tcontainsEntireContent(element) {\n\t\treturn this._selection.containsEntireContent(element);\n\t}\n\t/**\n\t* Unbinds all events previously bound by document selection.\n\t*/\n\tdestroy() {\n\t\tthis._selection.destroy();\n\t}\n\t/**\n\t* Returns iterable that iterates over this selection's attribute keys.\n\t*/\n\tgetAttributeKeys() {\n\t\treturn this._selection.getAttributeKeys();\n\t}\n\t/**\n\t* Returns iterable that iterates over this selection's attributes.\n\t*\n\t* Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t* This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t*/\n\tgetAttributes() {\n\t\treturn this._selection.getAttributes();\n\t}\n\t/**\n\t* Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.\n\t*\n\t* @param key Key of attribute to look for.\n\t* @returns Attribute value or `undefined`.\n\t*/\n\tgetAttribute(key) {\n\t\treturn this._selection.getAttribute(key);\n\t}\n\t/**\n\t* Checks if the selection has an attribute for given key.\n\t*\n\t* @param key Key of attribute to check.\n\t* @returns `true` if attribute with given key is set on selection, `false` otherwise.\n\t*/\n\thasAttribute(key) {\n\t\treturn this._selection.hasAttribute(key);\n\t}\n\t/**\n\t* Refreshes selection attributes and markers according to the current position in the model.\n\t*/\n\trefresh() {\n\t\tthis._selection.updateMarkers();\n\t\tthis._selection._updateAttributes(false);\n\t}\n\t/**\n\t* Registers a marker group prefix or a marker name to be collected in the\n\t* {@link ~ModelDocumentSelection#markers selection markers collection}.\n\t*\n\t* See also {@link module:engine/model/markercollection~MarkerCollection#getMarkersGroup `MarkerCollection#getMarkersGroup()`}.\n\t*\n\t* @param prefixOrName The marker group prefix or marker name.\n\t*/\n\tobserveMarkers(prefixOrName) {\n\t\tthis._selection.observeMarkers(prefixOrName);\n\t}\n\t/**\n\t* Converts `DocumentSelection` to plain object and returns it.\n\t*\n\t* @returns `DocumentSelection` converted to plain object.\n\t*/\n\ttoJSON() {\n\t\treturn this._selection.toJSON();\n\t}\n\t/**\n\t* Moves {@link module:engine/model/documentselection~ModelDocumentSelection#focus} to the specified location.\n\t* Should be used only within the {@link module:engine/model/writer~ModelWriter#setSelectionFocus} method.\n\t*\n\t* The location can be specified in the same form as\n\t* {@link module:engine/model/writer~ModelWriter#createPositionAt writer.createPositionAt()} parameters.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#setSelectionFocus\n\t* @internal\n\t* @param offset Offset or one of the flags. Used only when\n\t* first parameter is a {@link module:engine/model/item~ModelItem model item}.\n\t*/\n\t_setFocus(itemOrPosition, offset) {\n\t\tthis._selection.setFocus(itemOrPosition, offset);\n\t}\n\t/**\n\t* Sets this selection's ranges and direction to the specified location based on the given\n\t* {@link module:engine/model/selection~ModelSelectable selectable}.\n\t* Should be used only within the {@link module:engine/model/writer~ModelWriter#setSelection} method.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#setSelection\n\t* @internal\n\t*/\n\t_setTo(...args) {\n\t\tthis._selection.setTo(...args);\n\t}\n\t/**\n\t* Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t* Should be used only within the {@link module:engine/model/writer~ModelWriter#setSelectionAttribute} method.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#setSelectionAttribute\n\t* @internal\n\t* @param key Key of the attribute to set.\n\t* @param value Attribute value.\n\t*/\n\t_setAttribute(key, value) {\n\t\tthis._selection.setAttribute(key, value);\n\t}\n\t/**\n\t* Removes an attribute with given key from the selection.\n\t* If the given attribute was set on the selection, fires the {@link module:engine/model/selection~ModelSelection#event:change:range}\n\t* event with removed attribute key.\n\t* Should be used only within the {@link module:engine/model/writer~ModelWriter#removeSelectionAttribute} method.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#removeSelectionAttribute\n\t* @internal\n\t* @param key Key of the attribute to remove.\n\t*/\n\t_removeAttribute(key) {\n\t\tthis._selection.removeAttribute(key);\n\t}\n\t/**\n\t* Returns an iterable that iterates through all selection attributes stored in current selection's parent.\n\t*\n\t* @internal\n\t*/\n\t_getStoredAttributes() {\n\t\treturn this._selection.getStoredAttributes();\n\t}\n\t/**\n\t* Temporarily changes the gravity of the selection from the left to the right.\n\t*\n\t* The gravity defines from which direction the selection inherits its attributes. If it's the default left\n\t* gravity, the selection (after being moved by the the user) inherits attributes from its left hand side.\n\t* This method allows to temporarily override this behavior by forcing the gravity to the right.\n\t*\n\t* It returns an unique identifier which is required to restore the gravity. It guarantees the symmetry\n\t* of the process.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#overrideSelectionGravity\n\t* @internal\n\t* @returns The unique id which allows restoring the gravity.\n\t*/\n\t_overrideGravity() {\n\t\treturn this._selection.overrideGravity();\n\t}\n\t/**\n\t* Restores the {@link ~ModelDocumentSelection#_overrideGravity overridden gravity}.\n\t*\n\t* Restoring the gravity is only possible using the unique identifier returned by\n\t* {@link ~ModelDocumentSelection#_overrideGravity}. Note that the gravity remains overridden as long as won't be restored\n\t* the same number of times it was overridden.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#restoreSelectionGravity\n\t* @internal\n\t* @param uid The unique id returned by {@link #_overrideGravity}.\n\t*/\n\t_restoreGravity(uid) {\n\t\tthis._selection.restoreGravity(uid);\n\t}\n\t/**\n\t* Generates and returns an attribute key for selection attributes store, basing on original attribute key.\n\t*\n\t* @internal\n\t* @param key Attribute key to convert.\n\t* @returns Converted attribute key, applicable for selection store.\n\t*/\n\tstatic _getStoreAttributeKey(key) {\n\t\treturn storePrefix + key;\n\t}\n\t/**\n\t* Checks whether the given attribute key is an attribute stored on an element.\n\t*\n\t* @internal\n\t*/\n\tstatic _isStoreAttributeKey(key) {\n\t\treturn key.startsWith(storePrefix);\n\t}\n\t/**\n\t* Drop selection attribute key prefix.\n\t*\n\t* @internal\n\t*/\n\tstatic _dropStoreAttributeKeyPrefix(key) {\n\t\tif (key.startsWith(storePrefix)) return key.substring(10);\n\t\treturn key;\n\t}\n};\nModelDocumentSelection.prototype.is = function(type) {\n\treturn type === \"selection\" || type == \"model:selection\" || type == \"documentSelection\" || type == \"model:documentSelection\";\n};\n/**\n* `LiveSelection` is used internally by {@link module:engine/model/documentselection~ModelDocumentSelection}\n* and shouldn't be used directly.\n*\n* `LiveSelection` is automatically updated upon changes in the {@link module:engine/model/document~ModelDocument document}\n* to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.\n*\n* Differences between {@link module:engine/model/selection~ModelSelection} and `LiveSelection` are:\n* * there is always a range in `LiveSelection` - even if no ranges were added there is a \"default range\"\n* present in the selection,\n* * ranges added to this selection updates automatically when the document changes,\n* * attributes of `LiveSelection` are updated automatically according to selection ranges.\n*/\nvar LiveSelection = class extends ModelSelection {\n\t/**\n\t* List of selection markers.\n\t* Marker is a selection marker when selection range is inside the marker range.\n\t*/\n\tmarkers = new Collection({ idProperty: \"name\" });\n\t/**\n\t* Document which owns this selection.\n\t*/\n\t_model;\n\t/**\n\t* Document which owns this selection.\n\t*/\n\t_document;\n\t/**\n\t* Keeps mapping of attribute name to priority with which the attribute got modified (added/changed/removed)\n\t* last time. Possible values of priority are: `'low'` and `'normal'`.\n\t*\n\t* Priorities are used by internal `LiveSelection` mechanisms. All attributes set using `LiveSelection`\n\t* attributes API are set with `'normal'` priority.\n\t*/\n\t_attributePriority = /* @__PURE__ */ new Map();\n\t/**\n\t* Position to which the selection should be set if the last selection range was moved to the graveyard.\n\t*/\n\t_selectionRestorePosition = null;\n\t/**\n\t* Flag that informs whether the selection ranges have changed. It is changed on true when `LiveRange#change:range` event is fired.\n\t*/\n\t_hasChangedRange = false;\n\t/**\n\t* Each overriding gravity adds an UID to the set and each removal removes it.\n\t* Gravity is overridden when there's at least one UID in the set.\n\t* Gravity is restored when the set is empty.\n\t* This is to prevent conflicts when gravity is overridden by more than one feature at the same time.\n\t*/\n\t_overriddenGravityRegister = /* @__PURE__ */ new Set();\n\t/**\n\t* Prefixes of marker names that should affect `LiveSelection#markers` collection.\n\t*/\n\t_observedMarkers = /* @__PURE__ */ new Set();\n\t/**\n\t* Creates an empty live selection for given {@link module:engine/model/document~ModelDocument}.\n\t*\n\t* @param doc Document which owns this selection.\n\t*/\n\tconstructor(doc) {\n\t\tsuper();\n\t\tthis._model = doc.model;\n\t\tthis._document = doc;\n\t\tthis.listenTo(this._model, \"applyOperation\", (evt, args) => {\n\t\t\tconst operation = args[0];\n\t\t\tif (!operation.isDocumentOperation || operation.type == \"marker\" || operation.type == \"rename\" || operation.type == \"noop\") return;\n\t\t\tif (this._ranges.length == 0 && this._selectionRestorePosition) this._fixGraveyardSelection(this._selectionRestorePosition);\n\t\t\tthis._selectionRestorePosition = null;\n\t\t\tif (this._hasChangedRange) {\n\t\t\t\tthis._hasChangedRange = false;\n\t\t\t\tthis.fire(\"change:range\", { directChange: false });\n\t\t\t}\n\t\t}, { priority: \"lowest\" });\n\t\tthis.on(\"change:range\", () => {\n\t\t\tthis._validateSelectionRanges(this.getRanges());\n\t\t});\n\t\tthis.listenTo(this._model.markers, \"update\", (evt, marker, oldRange, newRange) => {\n\t\t\tthis._updateMarker(marker, newRange);\n\t\t});\n\t\tthis.listenTo(this._document, \"change\", (evt, batch) => {\n\t\t\tclearAttributesStoredInElement(this._model, batch);\n\t\t});\n\t}\n\tget isCollapsed() {\n\t\treturn this._ranges.length === 0 ? this._document._getDefaultRange().isCollapsed : super.isCollapsed;\n\t}\n\tget anchor() {\n\t\treturn super.anchor || this._document._getDefaultRange().start;\n\t}\n\tget focus() {\n\t\treturn super.focus || this._document._getDefaultRange().end;\n\t}\n\tget rangeCount() {\n\t\treturn this._ranges.length ? this._ranges.length : 1;\n\t}\n\t/**\n\t* Describes whether `LiveSelection` has own range(s) set, or if it is defaulted to\n\t* {@link module:engine/model/document~ModelDocument#_getDefaultRange document's default range}.\n\t*/\n\tget hasOwnRange() {\n\t\treturn this._ranges.length > 0;\n\t}\n\t/**\n\t* When set to `true` then selection attributes on node before the caret won't be taken\n\t* into consideration while updating selection attributes.\n\t*/\n\tget isGravityOverridden() {\n\t\treturn !!this._overriddenGravityRegister.size;\n\t}\n\t/**\n\t* Unbinds all events previously bound by live selection.\n\t*/\n\tdestroy() {\n\t\tfor (let i = 0; i < this._ranges.length; i++) this._ranges[i].detach();\n\t\tthis.stopListening();\n\t}\n\t*getRanges() {\n\t\tif (this._ranges.length) yield* super.getRanges();\n\t\telse yield this._document._getDefaultRange();\n\t}\n\tgetFirstRange() {\n\t\treturn super.getFirstRange() || this._document._getDefaultRange();\n\t}\n\tgetLastRange() {\n\t\treturn super.getLastRange() || this._document._getDefaultRange();\n\t}\n\tsetTo(...args) {\n\t\tsuper.setTo(...args);\n\t\tthis._updateAttributes(true);\n\t\tthis.updateMarkers();\n\t}\n\tsetFocus(itemOrPosition, offset) {\n\t\tsuper.setFocus(itemOrPosition, offset);\n\t\tthis._updateAttributes(true);\n\t\tthis.updateMarkers();\n\t}\n\tsetAttribute(key, value) {\n\t\tif (this._setAttribute(key, value)) {\n\t\t\tconst attributeKeys = [key];\n\t\t\tthis.fire(\"change:attribute\", {\n\t\t\t\tattributeKeys,\n\t\t\t\tdirectChange: true\n\t\t\t});\n\t\t}\n\t}\n\tremoveAttribute(key) {\n\t\tif (this._removeAttribute(key)) {\n\t\t\tconst attributeKeys = [key];\n\t\t\tthis.fire(\"change:attribute\", {\n\t\t\t\tattributeKeys,\n\t\t\t\tdirectChange: true\n\t\t\t});\n\t\t}\n\t}\n\toverrideGravity() {\n\t\tconst overrideUid = uid();\n\t\tthis._overriddenGravityRegister.add(overrideUid);\n\t\tif (this._overriddenGravityRegister.size === 1) this._updateAttributes(true);\n\t\treturn overrideUid;\n\t}\n\trestoreGravity(uid) {\n\t\tif (!this._overriddenGravityRegister.has(uid))\n /**\n\t\t* Restoring gravity for an unknown UID is not possible. Make sure you are using a correct\n\t\t* UID obtained from the {@link module:engine/model/writer~ModelWriter#overrideSelectionGravity} to restore.\n\t\t*\n\t\t* @error document-selection-gravity-wrong-restore\n\t\t* @param {string} uid The unique identifier returned by\n\t\t* {@link module:engine/model/documentselection~ModelDocumentSelection#_overrideGravity}.\n\t\t*/\n\t\tthrow new CKEditorError(\"document-selection-gravity-wrong-restore\", this, { uid });\n\t\tthis._overriddenGravityRegister.delete(uid);\n\t\tif (!this.isGravityOverridden) this._updateAttributes(true);\n\t}\n\tobserveMarkers(prefixOrName) {\n\t\tthis._observedMarkers.add(prefixOrName);\n\t\tthis.updateMarkers();\n\t}\n\t_replaceAllRanges(ranges) {\n\t\tthis._validateSelectionRanges(ranges);\n\t\tsuper._replaceAllRanges(ranges);\n\t}\n\t_popRange() {\n\t\tthis._ranges.pop().detach();\n\t}\n\t_pushRange(range) {\n\t\tconst liveRange = this._prepareRange(range);\n\t\tif (liveRange) this._ranges.push(liveRange);\n\t}\n\t/**\n\t* Converts `LiveSelection` to plain object and returns it.\n\t*\n\t* @returns `LiveSelection` converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tif (this.markers.length) json.markers = this.markers.map((marker) => marker.toJSON());\n\t\treturn json;\n\t}\n\t_validateSelectionRanges(ranges) {\n\t\tfor (const range of ranges) if (!this._document._validateSelectionRange(range))\n /**\n\t\t* Range from {@link module:engine/model/documentselection~ModelDocumentSelection document selection}\n\t\t* starts or ends at incorrect position.\n\t\t*\n\t\t* @error document-selection-wrong-position\n\t\t* @param {module:engine/model/range~ModelRange} range The invalid range.\n\t\t*/\n\t\tthrow new CKEditorError(\"document-selection-wrong-position\", this, { range });\n\t}\n\t/**\n\t* Prepares given range to be added to selection. Checks if it is correct,\n\t* converts it to {@link module:engine/model/liverange~ModelLiveRange ModelLiveRange}\n\t* and sets listeners listening to the range's change event.\n\t*/\n\t_prepareRange(range) {\n\t\tthis._checkRange(range);\n\t\tif (range.root == this._document.graveyard) return;\n\t\tconst liveRange = ModelLiveRange.fromRange(range);\n\t\tliveRange.on(\"change:range\", (evt, oldRange, data) => {\n\t\t\tthis._hasChangedRange = true;\n\t\t\tif (liveRange.root == this._document.graveyard) {\n\t\t\t\tthis._selectionRestorePosition = data.deletionPosition;\n\t\t\t\tconst index = this._ranges.indexOf(liveRange);\n\t\t\t\tthis._ranges.splice(index, 1);\n\t\t\t\tliveRange.detach();\n\t\t\t}\n\t\t});\n\t\treturn liveRange;\n\t}\n\tupdateMarkers() {\n\t\tif (!this._observedMarkers.size) return;\n\t\tconst markers = [];\n\t\tlet changed = false;\n\t\tfor (const marker of this._model.markers) {\n\t\t\tconst markerGroup = marker.name.split(\":\", 1)[0];\n\t\t\tif (!this._observedMarkers.has(markerGroup)) continue;\n\t\t\tconst markerRange = marker.getRange();\n\t\t\tfor (const selectionRange of this.getRanges()) if (markerRange.containsRange(selectionRange, !selectionRange.isCollapsed)) markers.push(marker);\n\t\t}\n\t\tconst oldMarkers = Array.from(this.markers);\n\t\tfor (const marker of markers) if (!this.markers.has(marker)) {\n\t\t\tthis.markers.add(marker);\n\t\t\tchanged = true;\n\t\t}\n\t\tfor (const marker of Array.from(this.markers)) if (!markers.includes(marker)) {\n\t\t\tthis.markers.remove(marker);\n\t\t\tchanged = true;\n\t\t}\n\t\tif (changed) this.fire(\"change:marker\", {\n\t\t\toldMarkers,\n\t\t\tdirectChange: false\n\t\t});\n\t}\n\t_updateMarker(marker, markerRange) {\n\t\tconst markerGroup = marker.name.split(\":\", 1)[0];\n\t\tif (!this._observedMarkers.has(markerGroup)) return;\n\t\tlet changed = false;\n\t\tconst oldMarkers = Array.from(this.markers);\n\t\tconst hasMarker = this.markers.has(marker);\n\t\tif (!markerRange) {\n\t\t\tif (hasMarker) {\n\t\t\t\tthis.markers.remove(marker);\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t} else {\n\t\t\tlet contained = false;\n\t\t\tfor (const selectionRange of this.getRanges()) if (markerRange.containsRange(selectionRange, !selectionRange.isCollapsed)) {\n\t\t\t\tcontained = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (contained && !hasMarker) {\n\t\t\t\tthis.markers.add(marker);\n\t\t\t\tchanged = true;\n\t\t\t} else if (!contained && hasMarker) {\n\t\t\t\tthis.markers.remove(marker);\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\t\tif (changed) this.fire(\"change:marker\", {\n\t\t\toldMarkers,\n\t\t\tdirectChange: false\n\t\t});\n\t}\n\t/**\n\t* Updates this selection attributes according to its ranges and the {@link module:engine/model/document~ModelDocument model document}.\n\t*/\n\t_updateAttributes(clearAll) {\n\t\tconst newAttributes = toMap(this._getSurroundingAttributes());\n\t\tconst oldAttributes = toMap(this.getAttributes());\n\t\tif (clearAll) {\n\t\t\tthis._attributePriority = /* @__PURE__ */ new Map();\n\t\t\tthis._attrs = /* @__PURE__ */ new Map();\n\t\t} else for (const [key, priority] of this._attributePriority) if (priority == \"low\") {\n\t\t\tthis._attrs.delete(key);\n\t\t\tthis._attributePriority.delete(key);\n\t\t}\n\t\tthis._setAttributesTo(newAttributes);\n\t\tconst changed = [];\n\t\tfor (const [newKey, newValue] of this.getAttributes()) if (!oldAttributes.has(newKey) || oldAttributes.get(newKey) !== newValue) changed.push(newKey);\n\t\tfor (const [oldKey] of oldAttributes) if (!this.hasAttribute(oldKey)) changed.push(oldKey);\n\t\tif (changed.length > 0) this.fire(\"change:attribute\", {\n\t\t\tattributeKeys: changed,\n\t\t\tdirectChange: false\n\t\t});\n\t}\n\t/**\n\t* Internal method for setting `LiveSelection` attribute. Supports attribute priorities (through `directChange`\n\t* parameter).\n\t*/\n\t_setAttribute(key, value, directChange = true) {\n\t\tconst priority = directChange ? \"normal\" : \"low\";\n\t\tif (priority == \"low\" && this._attributePriority.get(key) == \"normal\") return false;\n\t\tif (super.getAttribute(key) === value) return false;\n\t\tthis._attrs.set(key, value);\n\t\tthis._attributePriority.set(key, priority);\n\t\treturn true;\n\t}\n\t/**\n\t* Internal method for removing `LiveSelection` attribute. Supports attribute priorities (through `directChange`\n\t* parameter).\n\t*\n\t* NOTE: Even if attribute is not present in the selection but is provided to this method, it's priority will\n\t* be changed according to `directChange` parameter.\n\t*/\n\t_removeAttribute(key, directChange = true) {\n\t\tconst priority = directChange ? \"normal\" : \"low\";\n\t\tif (priority == \"low\" && this._attributePriority.get(key) == \"normal\") return false;\n\t\tthis._attributePriority.set(key, priority);\n\t\tif (!super.hasAttribute(key)) return false;\n\t\tthis._attrs.delete(key);\n\t\treturn true;\n\t}\n\t/**\n\t* Internal method for setting multiple `LiveSelection` attributes. Supports attribute priorities (through\n\t* `directChange` parameter).\n\t*/\n\t_setAttributesTo(attrs) {\n\t\tconst changed = /* @__PURE__ */ new Set();\n\t\tfor (const [oldKey, oldValue] of this.getAttributes()) {\n\t\t\tif (attrs.get(oldKey) === oldValue) continue;\n\t\t\tthis._removeAttribute(oldKey, false);\n\t\t}\n\t\tfor (const [key, value] of attrs) if (this._setAttribute(key, value, false)) changed.add(key);\n\t\treturn changed;\n\t}\n\t/**\n\t* Returns an iterable that iterates through all selection attributes stored in current selection's parent.\n\t*/\n\t*getStoredAttributes() {\n\t\tconst selectionParent = this.getFirstPosition().parent;\n\t\tif (this.isCollapsed && selectionParent.isEmpty) {\n\t\t\tfor (const key of selectionParent.getAttributeKeys()) if (key.startsWith(storePrefix)) yield [key.substr(10), selectionParent.getAttribute(key)];\n\t\t}\n\t}\n\t/**\n\t* Checks model text nodes that are closest to the selection's first position and returns attributes of first\n\t* found element. If there are no text nodes in selection's first position parent, it returns selection\n\t* attributes stored in that parent.\n\t*/\n\t_getSurroundingAttributes() {\n\t\tconst position = this.getFirstPosition();\n\t\tconst schema = this._model.schema;\n\t\tif (position.root.rootName == \"$graveyard\") return null;\n\t\tlet attrs = null;\n\t\tif (!this.isCollapsed) {\n\t\t\tconst range = this.getFirstRange();\n\t\t\tfor (const value of range) {\n\t\t\t\tif (value.item.is(\"element\") && schema.isObject(value.item)) {\n\t\t\t\t\tattrs = getTextAttributes(value.item, schema);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (value.type == \"text\") {\n\t\t\t\t\tattrs = value.item.getAttributes();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst nodeBefore = position.textNode ? position.textNode : position.nodeBefore;\n\t\t\tconst nodeAfter = position.textNode ? position.textNode : position.nodeAfter;\n\t\t\tif (!this.isGravityOverridden) attrs = getTextAttributes(nodeBefore, schema);\n\t\t\tif (!attrs) attrs = getTextAttributes(nodeAfter, schema);\n\t\t\tif (!this.isGravityOverridden && !attrs) attrs = getTextAttributes(nodeBefore, schema, \"backward\");\n\t\t\tif (!attrs) attrs = getTextAttributes(nodeAfter, schema, \"forward\");\n\t\t\tif (!attrs) attrs = this.getStoredAttributes();\n\t\t}\n\t\treturn attrs;\n\t}\n\t/**\n\t* Fixes the selection after all its ranges got removed.\n\t* @param deletionPosition Position where the deletion happened.\n\t*/\n\t_fixGraveyardSelection(deletionPosition) {\n\t\tconst selectionRange = this._model.schema.getNearestSelectionRange(deletionPosition);\n\t\tif (selectionRange) this._pushRange(selectionRange);\n\t}\n};\n/**\n* Helper function for {@link module:engine/model/liveselection~LiveSelection#_updateAttributes}.\n*\n* It checks if the passed model node is a text node and, if so, returns its attributes.\n* If not, it checks if item is an inline element and does the same. Otherwise, it returns `null`.\n*/\nfunction getTextAttributes(startNode, schema, scan = \"self\") {\n\tif (!startNode) return null;\n\tfor (const node of siblingNodes(startNode, scan)) {\n\t\tif (!node) return null;\n\t\tif (node instanceof ModelText) return node.getAttributes();\n\t\tif (!schema.isInline(node)) continue;\n\t\tconst isObject = schema.isObject(node);\n\t\tconst attributes = [];\n\t\tfor (const [key, value] of node.getAttributes()) if (schema.checkAttribute(\"$text\", key) && (!isObject || schema.getAttributeProperties(key).copyFromObject !== false)) attributes.push([key, value]);\n\t\treturn attributes;\n\t}\n\treturn null;\n}\n/**\n* Returns sibling nodes from the given start node.\n*/\nfunction* siblingNodes(startNode, scan) {\n\tif (scan == \"self\") yield startNode;\n\telse {\n\t\tlet node = startNode;\n\t\twhile (node) {\n\t\t\tnode = scan == \"backward\" ? node.previousSibling : node.nextSibling;\n\t\t\tyield node;\n\t\t}\n\t}\n\treturn null;\n}\n/**\n* Removes selection attributes from element which is not empty anymore.\n*/\nfunction clearAttributesStoredInElement(model, batch) {\n\tconst differ = model.document.differ;\n\tfor (const entry of differ.getChanges()) {\n\t\tif (entry.type != \"insert\") continue;\n\t\tconst changeParent = entry.position.parent;\n\t\tif (entry.length === changeParent.maxOffset) model.enqueueChange(batch, (writer) => {\n\t\t\tconst storedAttributes = Array.from(changeParent.getAttributeKeys()).filter((key) => key.startsWith(storePrefix));\n\t\t\tfor (const key of storedAttributes) writer.removeAttribute(key, changeParent);\n\t\t});\n\t}\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/nodelist\n*/\n/**\n* Provides an interface to operate on a list of {@link module:engine/model/node~ModelNode nodes}. `NodeList` is used internally\n* in classes like {@link module:engine/model/element~ModelElement Element}\n* or {@link module:engine/model/documentfragment~ModelDocumentFragment ModelDocumentFragment}.\n*/\nvar ModelNodeList = class {\n\t/**\n\t* Nodes contained in this node list.\n\t*/\n\t_nodes = [];\n\t/**\n\t* This array maps numbers (offsets) to node that is placed at that offset.\n\t*\n\t* This array is similar to `_nodes` with the difference that one node may occupy multiple consecutive items in the array.\n\t*\n\t* This array is needed to quickly retrieve a node that is placed at given offset.\n\t*/\n\t_offsetToNode = [];\n\t/**\n\t* Creates a node list.\n\t*\n\t* @internal\n\t* @param nodes Nodes contained in this node list.\n\t*/\n\tconstructor(nodes) {\n\t\tif (nodes) this._insertNodes(0, nodes);\n\t}\n\t/**\n\t* Iterable interface.\n\t*\n\t* Iterates over all nodes contained inside this node list.\n\t*/\n\t[Symbol.iterator]() {\n\t\treturn this._nodes[Symbol.iterator]();\n\t}\n\t/**\n\t* Number of nodes contained inside this node list.\n\t*/\n\tget length() {\n\t\treturn this._nodes.length;\n\t}\n\t/**\n\t* Sum of {@link module:engine/model/node~ModelNode#offsetSize offset sizes} of all nodes contained inside this node list.\n\t*/\n\tget maxOffset() {\n\t\treturn this._offsetToNode.length;\n\t}\n\t/**\n\t* Gets the node at the given index. Returns `null` if incorrect index was passed.\n\t*/\n\tgetNode(index) {\n\t\treturn this._nodes[index] || null;\n\t}\n\t/**\n\t* Gets the node at the given offset. Returns `null` if incorrect offset was passed.\n\t*/\n\tgetNodeAtOffset(offset) {\n\t\treturn this._offsetToNode[offset] || null;\n\t}\n\t/**\n\t* Returns an index of the given node or `null` if given node does not have a parent.\n\t*\n\t* This is an alias to {@link module:engine/model/node~ModelNode#index}.\n\t*/\n\tgetNodeIndex(node) {\n\t\treturn node.index;\n\t}\n\t/**\n\t* Returns the offset at which given node is placed in its parent or `null` if given node does not have a parent.\n\t*\n\t* This is an alias to {@link module:engine/model/node~ModelNode#startOffset}.\n\t*/\n\tgetNodeStartOffset(node) {\n\t\treturn node.startOffset;\n\t}\n\t/**\n\t* Converts index to offset in node list.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `model-nodelist-index-out-of-bounds` if given index is less\n\t* than `0` or more than {@link #length}.\n\t*/\n\tindexToOffset(index) {\n\t\tif (index == this._nodes.length) return this.maxOffset;\n\t\tconst node = this._nodes[index];\n\t\tif (!node)\n /**\n\t\t* Given index cannot be found in the node list.\n\t\t*\n\t\t* @error model-nodelist-index-out-of-bounds\n\t\t*/\n\t\tthrow new CKEditorError(\"model-nodelist-index-out-of-bounds\", this);\n\t\treturn this.getNodeStartOffset(node);\n\t}\n\t/**\n\t* Converts offset in node list to index.\n\t*\n\t* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `model-nodelist-offset-out-of-bounds` if given offset is less\n\t* than `0` or more than {@link #maxOffset}.\n\t*/\n\toffsetToIndex(offset) {\n\t\tif (offset == this._offsetToNode.length) return this._nodes.length;\n\t\tconst node = this._offsetToNode[offset];\n\t\tif (!node)\n /**\n\t\t* Given offset cannot be found in the node list.\n\t\t*\n\t\t* @error model-nodelist-offset-out-of-bounds\n\t\t* @param {number} offset The offset value.\n\t\t* @param {module:engine/model/nodelist~ModelNodeList} nodeList Stringified node list.\n\t\t*/\n\t\tthrow new CKEditorError(\"model-nodelist-offset-out-of-bounds\", this, {\n\t\t\toffset,\n\t\t\tnodeList: this\n\t\t});\n\t\treturn this.getNodeIndex(node);\n\t}\n\t/**\n\t* Inserts given nodes at given index.\n\t*\n\t* @internal\n\t* @param index Index at which nodes should be inserted.\n\t* @param nodes Nodes to be inserted.\n\t*/\n\t_insertNodes(index, nodes) {\n\t\tconst nodesArray = [];\n\t\tfor (const node of nodes) {\n\t\t\tif (!(node instanceof ModelNode))\n /**\n\t\t\t* Trying to insert an object which is not a Node instance.\n\t\t\t*\n\t\t\t* @error model-nodelist-insertnodes-not-node\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"model-nodelist-insertnodes-not-node\", this);\n\t\t\tnodesArray.push(node);\n\t\t}\n\t\tlet offset = this.indexToOffset(index);\n\t\tspliceArray(this._nodes, nodesArray, index);\n\t\tspliceArray(this._offsetToNode, makeOffsetsArray(nodesArray), offset);\n\t\tfor (let i = index; i < this._nodes.length; i++) {\n\t\t\tthis._nodes[i]._index = i;\n\t\t\tthis._nodes[i]._startOffset = offset;\n\t\t\toffset += this._nodes[i].offsetSize;\n\t\t}\n\t}\n\t/**\n\t* Removes one or more nodes starting at the given index.\n\t*\n\t* @internal\n\t* @param indexStart Index of the first node to remove.\n\t* @param howMany Number of nodes to remove.\n\t* @returns Array containing removed nodes.\n\t*/\n\t_removeNodes(indexStart, howMany = 1) {\n\t\tif (howMany == 0) return [];\n\t\tlet offset = this.indexToOffset(indexStart);\n\t\tconst nodes = this._nodes.splice(indexStart, howMany);\n\t\tconst lastNode = nodes[nodes.length - 1];\n\t\tconst removedOffsetSum = lastNode.startOffset + lastNode.offsetSize - offset;\n\t\tthis._offsetToNode.splice(offset, removedOffsetSum);\n\t\tfor (const node of nodes) {\n\t\t\tnode._index = null;\n\t\t\tnode._startOffset = null;\n\t\t}\n\t\tfor (let i = indexStart; i < this._nodes.length; i++) {\n\t\t\tthis._nodes[i]._index = i;\n\t\t\tthis._nodes[i]._startOffset = offset;\n\t\t\toffset += this._nodes[i].offsetSize;\n\t\t}\n\t\treturn nodes;\n\t}\n\t/**\n\t* Removes children nodes provided as an array. These nodes do not need to be direct siblings.\n\t*\n\t* This method is faster than removing nodes one by one, as it recalculates offsets only once.\n\t*\n\t* @internal\n\t* @param nodes Array of nodes.\n\t*/\n\t_removeNodesArray(nodes) {\n\t\tif (nodes.length == 0) return;\n\t\tfor (const node of nodes) {\n\t\t\tnode._index = null;\n\t\t\tnode._startOffset = null;\n\t\t}\n\t\tthis._nodes = this._nodes.filter((node) => node.index !== null);\n\t\tthis._offsetToNode = this._offsetToNode.filter((node) => node.index !== null);\n\t\tlet offset = 0;\n\t\tfor (let i = 0; i < this._nodes.length; i++) {\n\t\t\tthis._nodes[i]._index = i;\n\t\t\tthis._nodes[i]._startOffset = offset;\n\t\t\toffset += this._nodes[i].offsetSize;\n\t\t}\n\t}\n\t/**\n\t* Converts `NodeList` instance to an array containing nodes that were inserted in the node list. Nodes\n\t* are also converted to their plain object representation.\n\t*\n\t* @returns `NodeList` instance converted to `Array`.\n\t*/\n\ttoJSON() {\n\t\treturn this._nodes.map((node) => node.toJSON());\n\t}\n};\n/**\n* Creates an array of nodes in the format as in {@link module:engine/model/nodelist~ModelNodeList#_offsetToNode}, i.e. one node will\n* occupy multiple items if its offset size is greater than one.\n*/\nfunction makeOffsetsArray(nodes) {\n\tconst offsets = [];\n\tlet index = 0;\n\tfor (const node of nodes) for (let i = 0; i < node.offsetSize; i++) offsets[index++] = node;\n\treturn offsets;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/element\n*/\n/**\n* Model element. Type of {@link module:engine/model/node~ModelNode node} that has a\n* {@link module:engine/model/element~ModelElement#name name} and {@link module:engine/model/element~ModelElement#getChildren child nodes}.\n*\n* **Important**: see {@link module:engine/model/node~ModelNode} to read about restrictions using `Element` and `Node` API.\n*/\nvar ModelElement = class ModelElement extends ModelNode {\n\t/**\n\t* Element name.\n\t*/\n\tname;\n\t/**\n\t* List of children nodes.\n\t*/\n\t_children = new ModelNodeList();\n\t/**\n\t* Creates a model element.\n\t*\n\t* **Note:** Constructor of this class shouldn't be used directly in the code.\n\t* Use the {@link module:engine/model/writer~ModelWriter#createElement} method instead.\n\t*\n\t* @internal\n\t* @param name Element's name.\n\t* @param attrs Element's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t* @param children One or more nodes to be inserted as children of created element.\n\t*/\n\tconstructor(name, attrs, children) {\n\t\tsuper(attrs);\n\t\tthis.name = name;\n\t\tif (children) this._insertChild(0, children);\n\t}\n\t/**\n\t* Number of this element's children.\n\t*/\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\t/**\n\t* Sum of {@link module:engine/model/node~ModelNode#offsetSize offset sizes} of all of this element's children.\n\t*/\n\tget maxOffset() {\n\t\treturn this._children.maxOffset;\n\t}\n\t/**\n\t* Is `true` if there are no nodes inside this element, `false` otherwise.\n\t*/\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\t/**\n\t* Gets the child at the given index. Returns `null` if incorrect index was passed.\n\t*\n\t* @param index Index in this element.\n\t* @returns Child node.\n\t*/\n\tgetChild(index) {\n\t\treturn this._children.getNode(index);\n\t}\n\t/**\n\t* Gets the child at the given offset. Returns `null` if incorrect index was passed.\n\t*\n\t* @param offset Offset in this element.\n\t* @returns Child node.\n\t*/\n\tgetChildAtOffset(offset) {\n\t\treturn this._children.getNodeAtOffset(offset);\n\t}\n\t/**\n\t* Returns an iterator that iterates over all of this element's children.\n\t*/\n\tgetChildren() {\n\t\treturn this._children[Symbol.iterator]();\n\t}\n\t/**\n\t* Returns an index of the given child node. Returns `null` if given node is not a child of this element.\n\t*\n\t* @param node Child node to look for.\n\t* @returns Child node's index in this element.\n\t*/\n\tgetChildIndex(node) {\n\t\treturn this._children.getNodeIndex(node);\n\t}\n\t/**\n\t* Returns the starting offset of given child. Starting offset is equal to the sum of\n\t* {@link module:engine/model/node~ModelNode#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if\n\t* given node is not a child of this element.\n\t*\n\t* @param node Child node to look for.\n\t* @returns Child node's starting offset.\n\t*/\n\tgetChildStartOffset(node) {\n\t\treturn this._children.getNodeStartOffset(node);\n\t}\n\t/**\n\t* Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is\n\t* too high, returns {@link module:engine/model/element~ModelElement#getChildIndex index after last child}.\n\t*\n\t* ```ts\n\t* const textNode = new Text( 'foo' );\n\t* const pElement = new Element( 'p' );\n\t* const divElement = new Element( [ textNode, pElement ] );\n\t* divElement.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t* divElement.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t* divElement.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t* divElement.offsetToIndex( 2 ); // Returns 0.\n\t* divElement.offsetToIndex( 3 ); // Returns 1.\n\t* divElement.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t* ```\n\t*/\n\toffsetToIndex(offset) {\n\t\treturn this._children.offsetToIndex(offset);\n\t}\n\t/**\n\t* Returns a descendant node by its path relative to this element.\n\t*\n\t* ```ts\n\t* // <this>a<b>c</b></this>\n\t* this.getNodeByPath( [ 0 ] ); // -> \"a\"\n\t* this.getNodeByPath( [ 1 ] ); // -> <b>\n\t* this.getNodeByPath( [ 1, 0 ] ); // -> \"c\"\n\t* ```\n\t*\n\t* @param relativePath Path of the node to find, relative to this element.\n\t*/\n\tgetNodeByPath(relativePath) {\n\t\tlet node = this;\n\t\tfor (const offset of relativePath) node = node.getChildAtOffset(offset);\n\t\treturn node;\n\t}\n\t/**\n\t* Returns the parent element of the given name. Returns null if the element is not inside the desired parent.\n\t*\n\t* @param parentName The name of the parent element to find.\n\t* @param options Options object.\n\t* @param options.includeSelf When set to `true` this node will be also included while searching.\n\t*/\n\tfindAncestor(parentName, options = {}) {\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\t\twhile (parent) {\n\t\t\tif (parent.name === parentName) return parent;\n\t\t\tparent = parent.parent;\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Converts `Element` instance to plain object and returns it. Takes care of converting all of this element's children.\n\t*\n\t* @returns `Element` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.name = this.name;\n\t\tif (this._children.length > 0) {\n\t\t\tjson.children = [];\n\t\t\tfor (const node of this._children) json.children.push(node.toJSON());\n\t\t}\n\t\treturn json;\n\t}\n\t/**\n\t* Creates a copy of this element and returns it. Created element has the same name and attributes as the original element.\n\t* If clone is deep, the original element's children are also cloned. If not, then empty element is returned.\n\t*\n\t* @internal\n\t* @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t* element will be cloned without any child.\n\t*/\n\t_clone(deep = false) {\n\t\tconst children = deep ? cloneNodes(this._children) : void 0;\n\t\treturn new ModelElement(this.name, this.getAttributes(), children);\n\t}\n\t/**\n\t* {@link module:engine/model/element~ModelElement#_insertChild Inserts} one or more nodes at the end of this element.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#append\n\t* @internal\n\t* @param nodes Nodes to be inserted.\n\t*/\n\t_appendChild(nodes) {\n\t\tthis._insertChild(this.childCount, nodes);\n\t}\n\t/**\n\t* Inserts one or more nodes at the given index and sets {@link module:engine/model/node~ModelNode#parent parent} of these nodes\n\t* to this element.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#insert\n\t* @internal\n\t* @param index Index at which nodes should be inserted.\n\t* @param items Items to be inserted.\n\t*/\n\t_insertChild(index, items) {\n\t\tconst nodes = normalize$1(items);\n\t\tfor (const node of nodes) {\n\t\t\tif (node.parent !== null) node._remove();\n\t\t\tnode.parent = this;\n\t\t}\n\t\tthis._children._insertNodes(index, nodes);\n\t}\n\t/**\n\t* Removes one or more nodes starting at the given index and sets\n\t* {@link module:engine/model/node~ModelNode#parent parent} of these nodes to `null`.\n\t*\n\t* @see module:engine/model/writer~ModelWriter#remove\n\t* @internal\n\t* @param index Index of the first node to remove.\n\t* @param howMany Number of nodes to remove.\n\t* @returns Array containing removed nodes.\n\t*/\n\t_removeChildren(index, howMany = 1) {\n\t\tconst nodes = this._children._removeNodes(index, howMany);\n\t\tfor (const node of nodes) node.parent = null;\n\t\treturn nodes;\n\t}\n\t/**\n\t* Removes children nodes provided as an array and sets\n\t* the {@link module:engine/model/node~ModelNode#parent parent} of these nodes to `null`.\n\t*\n\t* These nodes do not need to be direct siblings.\n\t*\n\t* This method is faster than removing nodes one by one, as it recalculates offsets only once.\n\t*\n\t* @internal\n\t* @param nodes Array of nodes.\n\t*/\n\t_removeChildrenArray(nodes) {\n\t\tthis._children._removeNodesArray(nodes);\n\t\tfor (const node of nodes) node.parent = null;\n\t}\n\t/**\n\t* Creates an `Element` instance from given plain object (i.e. parsed JSON string).\n\t* Converts `Element` children to proper nodes.\n\t*\n\t* @param json Plain object to be converted to `Element`.\n\t* @returns `Element` instance created using given plain object.\n\t*/\n\tstatic fromJSON(json) {\n\t\tlet children;\n\t\tif (json.children) {\n\t\t\tchildren = [];\n\t\t\tfor (const child of json.children) if (child.name) children.push(ModelElement.fromJSON(child));\n\t\t\telse children.push(ModelText.fromJSON(child));\n\t\t}\n\t\treturn new ModelElement(json.name, json.attributes, children);\n\t}\n};\nModelElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"element\" || type === \"model:element\" || type === \"node\" || type === \"model:node\";\n\treturn name === this.name && (type === \"element\" || type === \"model:element\");\n};\n/**\n* Converts strings to Text and non-iterables to arrays.\n*/\nfunction normalize$1(nodes) {\n\tif (typeof nodes == \"string\") return [new ModelText(nodes)];\n\tif (!isIterable(nodes)) nodes = [nodes];\n\tconst normalizedNodes = [];\n\tfor (const node of nodes) if (typeof node == \"string\") normalizedNodes.push(new ModelText(node));\n\telse if (node instanceof ModelTextProxy) normalizedNodes.push(new ModelText(node.data, node.getAttributes()));\n\telse normalizedNodes.push(node);\n\treturn normalizedNodes;\n}\nfunction cloneNodes(nodes) {\n\tconst clonedNodes = [];\n\tfor (const node of nodes) clonedNodes.push(node._clone(true));\n\treturn clonedNodes;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/conversion/conversionhelpers\n*/\n/**\n* Base class for conversion helpers.\n*/\nvar ConversionHelpers = class {\n\t_dispatchers;\n\t/**\n\t* Creates a conversion helpers instance.\n\t*/\n\tconstructor(dispatchers) {\n\t\tthis._dispatchers = dispatchers;\n\t}\n\t/**\n\t* Registers a conversion helper.\n\t*\n\t* **Note**: See full usage example in the `{@link module:engine/conversion/conversion~Conversion#for conversion.for()}`\n\t* method description.\n\t*\n\t* @param conversionHelper The function to be called on event.\n\t*/\n\tadd(conversionHelper) {\n\t\tfor (const dispatcher of this._dispatchers) conversionHelper(dispatcher);\n\t\treturn this;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Contains downcast (model-to-view) converters for {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}.\n*\n* @module engine/conversion/downcasthelpers\n*/\n/**\n* Downcast conversion helper functions.\n*\n* Learn more about {@glink framework/deep-dive/conversion/downcast downcast helpers}.\n*\n* @extends module:engine/conversion/conversionhelpers~ConversionHelpers\n*/\nvar DowncastHelpers = class extends ConversionHelpers {\n\t/**\n\t* Model element to view element conversion helper.\n\t*\n\t* This conversion results in creating a view element. For example, model `<paragraph>Foo</paragraph>` becomes `<p>Foo</p>` in the view.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' ).elementToElement( {\n\t* \tmodel: 'paragraph',\n\t* \tview: 'p'\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).elementToElement( {\n\t* \tmodel: 'paragraph',\n\t* \tview: 'div',\n\t* \tconverterPriority: 'high'\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).elementToElement( {\n\t* \tmodel: 'fancyParagraph',\n\t* \tview: {\n\t* \t\tname: 'p',\n\t* \t\tclasses: 'fancy'\n\t* \t}\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).elementToElement( {\n\t* \tmodel: 'heading',\n\t* \tview: ( modelElement, conversionApi ) => {\n\t* \t\tconst { writer } = conversionApi;\n\t*\n\t* \t\treturn writer.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) );\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* The element-to-element conversion supports the reconversion mechanism. It can be enabled by using either the `attributes` or\n\t* the `children` props on a model description. You will find a couple examples below.\n\t*\n\t* In order to reconvert an element if any of its direct children have been added or removed, use the `children` property on a `model`\n\t* description. For example, this model:\n\t*\n\t* ```xml\n\t* <box>\n\t* \t<paragraph>Some text.</paragraph>\n\t* </box>\n\t* ```\n\t*\n\t* will be converted into this structure in the view:\n\t*\n\t* ```html\n\t* <div class=\"box\" data-type=\"single\">\n\t* \t<p>Some text.</p>\n\t* </div>\n\t* ```\n\t*\n\t* But if more items were inserted in the model:\n\t*\n\t* ```xml\n\t* <box>\n\t* \t<paragraph>Some text.</paragraph>\n\t* \t<paragraph>Other item.</paragraph>\n\t* </box>\n\t* ```\n\t*\n\t* it will be converted into this structure in the view (note the element `data-type` change):\n\t*\n\t* ```html\n\t* <div class=\"box\" data-type=\"multiple\">\n\t* \t<p>Some text.</p>\n\t* \t<p>Other item.</p>\n\t* </div>\n\t* ```\n\t*\n\t* Such a converter would look like this (note that the `paragraph` elements are converted separately):\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' ).elementToElement( {\n\t* \tmodel: {\n\t* \t\tname: 'box',\n\t* \t\tchildren: true\n\t* \t},\n\t* \tview: ( modelElement, conversionApi ) => {\n\t* \t\tconst { writer } = conversionApi;\n\t*\n\t* \t\treturn writer.createContainerElement( 'div', {\n\t* \t\t\tclass: 'box',\n\t* \t\t\t'data-type': modelElement.childCount == 1 ? 'single' : 'multiple'\n\t* \t\t} );\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* In order to reconvert element if any of its attributes have been updated, use the `attributes` property on a `model`\n\t* description. For example, this model:\n\t*\n\t* ```xml\n\t* <heading level=\"2\">Some text.</heading>\n\t* ```\n\t*\n\t* will be converted into this structure in the view:\n\t*\n\t* ```html\n\t* <h2>Some text.</h2>\n\t* ```\n\t*\n\t* But if the `heading` element's `level` attribute has been updated to `3` for example, then\n\t* it will be converted into this structure in the view:\n\t*\n\t* ```html\n\t* <h3>Some text.</h3>\n\t* ```\n\t*\n\t* Such a converter would look as follows:\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' ).elementToElement( {\n\t* \tmodel: {\n\t* \t\tname: 'heading',\n\t* \t\tattributes: 'level'\n\t* \t},\n\t* \tview: ( modelElement, conversionApi ) => {\n\t* \t\tconst { writer } = conversionApi;\n\t*\n\t* \t\treturn writer.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) );\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* You can read more about the element-to-element conversion in the\n\t* {@glink framework/deep-dive/conversion/downcast downcast conversion} guide.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.model The description or a name of the model element to convert.\n\t* @param config.view A view element definition or a function that takes the model element and\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t* as parameters and returns a view container element.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\telementToElement(config) {\n\t\treturn this.add(downcastElementToElement(config));\n\t}\n\t/**\n\t* The model element to view structure (several elements) conversion helper.\n\t*\n\t* This conversion results in creating a view structure with one or more slots defined for the child nodes.\n\t* For example, a model `<table>` may become this structure in the view:\n\t*\n\t* ```html\n\t* <figure class=\"table\">\n\t* \t<table>\n\t* \t\t<tbody>${ slot for table rows }</tbody>\n\t* \t</table>\n\t* </figure>\n\t* ```\n\t*\n\t* The children of the model's `<table>` element will be inserted into the `<tbody>` element.\n\t* If the `elementToElement()` helper was used, the children would be inserted into the `<figure>`.\n\t*\n\t* Imagine a table feature where for this model structure:\n\t*\n\t* ```xml\n\t* <table headingRows=\"1\">\n\t* \t<tableRow> ... table cells 1 ... </tableRow>\n\t* \t<tableRow> ... table cells 2 ... </tableRow>\n\t* \t<tableRow> ... table cells 3 ... </tableRow>\n\t* \t<caption>Caption text</caption>\n\t* </table>\n\t* ```\n\t*\n\t* we want to generate this view structure:\n\t*\n\t* ```html\n\t* <figure class=\"table\">\n\t* \t<table>\n\t* \t\t<thead>\n\t* \t\t\t<tr> ... table cells 1 ... </tr>\n\t* \t\t</thead>\n\t* \t\t<tbody>\n\t* \t\t\t<tr> ... table cells 2 ... </tr>\n\t* \t\t\t<tr> ... table cells 3 ... </tr>\n\t* \t\t</tbody>\n\t* \t</table>\n\t* \t<figcaption>Caption text</figcaption>\n\t* </figure>\n\t* ```\n\t*\n\t* The converter has to take the `headingRows` attribute into consideration when allocating the `<tableRow>` elements\n\t* into the `<tbody>` and `<thead>` elements. Hence, we need two slots and need to define proper filter callbacks for them.\n\t*\n\t* Additionally, all elements other than `<tableRow>` should be placed outside the `<table>` tag.\n\t* In the example above, this will handle the table caption.\n\t*\n\t* Such a converter would look like this:\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' ).elementToStructure( {\n\t* \tmodel: {\n\t* \t\tname: 'table',\n\t* \t\tattributes: [ 'headingRows' ]\n\t* \t},\n\t* \tview: ( modelElement, conversionApi ) => {\n\t* \t\tconst { writer } = conversionApi;\n\t*\n\t* \t\tconst figureElement = writer.createContainerElement( 'figure', { class: 'table' } );\n\t* \t\tconst tableElement = writer.createContainerElement( 'table' );\n\t*\n\t* \t\twriter.insert( writer.createPositionAt( figureElement, 0 ), tableElement );\n\t*\n\t* \t\tconst headingRows = modelElement.getAttribute( 'headingRows' ) || 0;\n\t*\n\t* \t\tif ( headingRows > 0 ) {\n\t* \t\t\tconst tableHead = writer.createContainerElement( 'thead' );\n\t*\n\t* \t\t\tconst headSlot = writer.createSlot( node => node.is( 'element', 'tableRow' ) && node.index < headingRows );\n\t*\n\t* \t\t\twriter.insert( writer.createPositionAt( tableElement, 'end' ), tableHead );\n\t* \t\t\twriter.insert( writer.createPositionAt( tableHead, 0 ), headSlot );\n\t* \t\t}\n\t*\n\t* \t\tif ( headingRows < tableUtils.getRows( table ) ) {\n\t* \t\t\tconst tableBody = writer.createContainerElement( 'tbody' );\n\t*\n\t* \t\t\tconst bodySlot = writer.createSlot( node => node.is( 'element', 'tableRow' ) && node.index >= headingRows );\n\t*\n\t* \t\t\twriter.insert( writer.createPositionAt( tableElement, 'end' ), tableBody );\n\t* \t\t\twriter.insert( writer.createPositionAt( tableBody, 0 ), bodySlot );\n\t* \t\t}\n\t*\n\t* \t\tconst restSlot = writer.createSlot( node => !node.is( 'element', 'tableRow' ) );\n\t*\n\t* \t\twriter.insert( writer.createPositionAt( figureElement, 'end' ), restSlot );\n\t*\n\t* \t\treturn figureElement;\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* Note: The children of a model element that's being converted must be allocated in the same order in the view\n\t* in which they are placed in the model.\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.model The description or a name of the model element to convert.\n\t* @param config.view A function that takes the model element and\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters\n\t* and returns a view container element with slots for model child nodes to be converted into.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\telementToStructure(config) {\n\t\treturn this.add(downcastElementToStructure(config));\n\t}\n\t/**\n\t* Model attribute to view element conversion helper.\n\t*\n\t* This conversion results in wrapping view nodes with a view attribute element. For example, a model text node with\n\t* `\"Foo\"` as data and the `bold` attribute becomes `<strong>Foo</strong>` in the view.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' ).attributeToElement( {\n\t* \tmodel: 'bold',\n\t* \tview: 'strong'\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToElement( {\n\t* \tmodel: 'bold',\n\t* \tview: 'b',\n\t* \tconverterPriority: 'high'\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToElement( {\n\t* \tmodel: 'invert',\n\t* \tview: {\n\t* \t\tname: 'span',\n\t* \t\tclasses: [ 'font-light', 'bg-dark' ]\n\t* \t}\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToElement( {\n\t* \tmodel: {\n\t* \t\tkey: 'fontSize',\n\t* \t\tvalues: [ 'big', 'small' ]\n\t* \t},\n\t* \tview: {\n\t* \t\tbig: {\n\t* \t\t\tname: 'span',\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'font-size': '1.2em'\n\t* \t\t\t}\n\t* \t\t},\n\t* \t\tsmall: {\n\t* \t\t\tname: 'span',\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'font-size': '0.8em'\n\t* \t\t\t}\n\t* \t\t}\n\t* \t}\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToElement( {\n\t* \tmodel: 'bold',\n\t* \tview: ( modelAttributeValue, conversionApi ) => {\n\t* \t\tconst { writer } = conversionApi;\n\t*\n\t* \t\treturn writer.createAttributeElement( 'span', {\n\t* \t\t\tstyle: 'font-weight:' + modelAttributeValue\n\t* \t\t} );\n\t* \t}\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToElement( {\n\t* \tmodel: {\n\t* \t\tkey: 'color',\n\t* \t\tname: '$text'\n\t* \t},\n\t* \tview: ( modelAttributeValue, conversionApi ) => {\n\t* \t\tconst { writer } = conversionApi;\n\t*\n\t* \t\treturn writer.createAttributeElement( 'span', {\n\t* \t\t\tstyle: 'color:' + modelAttributeValue\n\t* \t\t} );\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.model The key of the attribute to convert from or a `{ key, values }` object. `values` is an array\n\t* of `String`s with possible values if the model attribute is an enumerable.\n\t* @param config.view A view element definition or a function\n\t* that takes the model attribute value and\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters and returns a view\n\t* attribute element. If `config.model.values` is given, `config.view` should be an object assigning values from `config.model.values`\n\t* to view element definitions or functions.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\tattributeToElement(config) {\n\t\treturn this.add(downcastAttributeToElement(config));\n\t}\n\t/**\n\t* Model attribute to view attribute conversion helper.\n\t*\n\t* This conversion results in adding an attribute to a view node, basing on an attribute from a model node. For example,\n\t* `<imageInline src='foo.jpg'></imageInline>` is converted to `<img src='foo.jpg'></img>`.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t* \tmodel: 'source',\n\t* \tview: 'src'\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t* \tmodel: 'source',\n\t* \tview: 'href',\n\t* \tconverterPriority: 'high'\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t* \tmodel: {\n\t* \t\tname: 'imageInline',\n\t* \t\tkey: 'source'\n\t* \t},\n\t* \tview: 'src'\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t* \tmodel: {\n\t* \t\tname: 'styled',\n\t* \t\tvalues: [ 'dark', 'light' ]\n\t* \t},\n\t* \tview: {\n\t* \t\tdark: {\n\t* \t\t\tkey: 'class',\n\t* \t\t\tvalue: [ 'styled', 'styled-dark' ]\n\t* \t\t},\n\t* \t\tlight: {\n\t* \t\t\tkey: 'class',\n\t* \t\t\tvalue: [ 'styled', 'styled-light' ]\n\t* \t\t}\n\t* \t}\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t* \tmodel: 'styled',\n\t* \tview: modelAttributeValue => ( {\n\t* \t\tkey: 'class',\n\t* \t\tvalue: 'styled-' + modelAttributeValue\n\t* \t} )\n\t* } );\n\t* ```\n\t*\n\t* **Note**: Downcasting to a style property requires providing `value` as an object:\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t* \tmodel: 'lineHeight',\n\t* \tview: modelAttributeValue => ( {\n\t* \t\tkey: 'style',\n\t* \t\tvalue: {\n\t* \t\t\t'line-height': modelAttributeValue,\n\t* \t\t\t'border-bottom': '1px dotted #ba2'\n\t* \t\t}\n\t* \t} )\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.model The key of the attribute to convert from or a `{ key, values, [ name ] }` object describing\n\t* the attribute key, possible values and, optionally, an element name to convert from.\n\t* @param config.view A view attribute key, or a `{ key, value }` object or a function that takes the model attribute value and\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t* as parameters and returns a `{ key, value }` object. If the `key` is `'class'`, the `value` can be a `String` or an\n\t* array of `String`s. If the `key` is `'style'`, the `value` is an object with key-value pairs. In other cases, `value` is a `String`.\n\t* If `config.model.values` is set, `config.view` should be an object assigning values from `config.model.values` to\n\t* `{ key, value }` objects or a functions.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\tattributeToAttribute(config) {\n\t\treturn this.add(downcastAttributeToAttribute(config));\n\t}\n\t/**\n\t* Model marker to view element conversion helper.\n\t*\n\t* **Note**: This method should be used mainly for editing the downcast and it is recommended\n\t* to use the {@link #markerToData `#markerToData()`} helper instead.\n\t*\n\t* This helper may produce invalid HTML code (e.g. a span between table cells).\n\t* It should only be used when you are sure that the produced HTML will be semantically correct.\n\t*\n\t* This conversion results in creating a view element on the boundaries of the converted marker. If the converted marker\n\t* is collapsed, only one element is created. For example, a model marker set like this: `<paragraph>F[oo b]ar</paragraph>`\n\t* becomes `<p>F<span data-marker=\"search\"></span>oo b<span data-marker=\"search\"></span>ar</p>` in the view.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t* \tmodel: 'search',\n\t* \tview: 'marker-search'\n\t* } );\n\t*\n\t* editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t* \tmodel: 'search',\n\t* \tview: 'search-result',\n\t* \tconverterPriority: 'high'\n\t* } );\n\t*\n\t* editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t* \tmodel: 'search',\n\t* \tview: {\n\t* \t\tname: 'span',\n\t* \t\tattributes: {\n\t* \t\t\t'data-marker': 'search'\n\t* \t\t}\n\t* \t}\n\t* } );\n\t*\n\t* editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t* \tmodel: 'search',\n\t* \tview: ( markerData, conversionApi ) => {\n\t* \t\tconst { writer } = conversionApi;\n\t*\n\t* \t\treturn writer.createUIElement( 'span', {\n\t* \t\t\t'data-marker': 'search',\n\t* \t\t\t'data-start': markerData.isOpening\n\t* \t\t} );\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* If a function is passed as the `config.view` parameter, it will be used to generate both boundary elements. The function\n\t* receives the `data` object and {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t* as a parameters and should return an instance of the\n\t* {@link module:engine/view/uielement~ViewUIElement view UI element}. The `data` object and\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi `conversionApi`} are passed from\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}. Additionally,\n\t* the `data.isOpening` parameter is passed, which is set to `true` for the marker start boundary element, and `false` for\n\t* the marker end boundary element.\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.model The name of the model marker (or model marker group) to convert.\n\t* @param config.view A view element definition or a function that takes the model marker data and\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as a parameters\n\t* and returns a view UI element.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\tmarkerToElement(config) {\n\t\treturn this.add(downcastMarkerToElement(config));\n\t}\n\t/**\n\t* Model marker to highlight conversion helper.\n\t*\n\t* This conversion results in creating a highlight on view nodes. For this kind of conversion,\n\t* the {@link module:engine/conversion/downcasthelpers~DowncastHighlightDescriptor} should be provided.\n\t*\n\t* For text nodes, a `<span>` {@link module:engine/view/attributeelement~ViewAttributeElement} is created and it wraps all text nodes\n\t* in the converted marker range. For example, a model marker set like this: `<paragraph>F[oo b]ar</paragraph>` becomes\n\t* `<p>F<span class=\"comment\">oo b</span>ar</p>` in the view.\n\t*\n\t* {@link module:engine/view/containerelement~ViewContainerElement} may provide a custom way of handling highlight. Most often,\n\t* the element itself is given classes and attributes described in the highlight descriptor (instead of being wrapped in `<span>`).\n\t* For example, a model marker set like this:\n\t* `[<imageInline src=\"foo.jpg\"></imageInline>]` becomes `<img src=\"foo.jpg\" class=\"comment\"></img>` in the view.\n\t*\n\t* For container elements, the conversion is two-step. While the converter processes the highlight descriptor and passes it\n\t* to a container element, it is the container element instance itself that applies values from the highlight descriptor.\n\t* So, in a sense, the converter takes care of stating what should be applied on what, while the element decides how to apply that.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' ).markerToHighlight( { model: 'comment', view: { classes: 'comment' } } );\n\t*\n\t* editor.conversion.for( 'downcast' ).markerToHighlight( {\n\t* \tmodel: 'comment',\n\t* \tview: { classes: 'comment' },\n\t* \tconverterPriority: 'high'\n\t* } );\n\t*\n\t* editor.conversion.for( 'downcast' ).markerToHighlight( {\n\t* \tmodel: 'comment',\n\t* \tview: ( data, conversionApi ) => {\n\t* \t\t// Assuming that the marker name is in a form of comment:commentType:commentId.\n\t* \t\tconst [ , commentType, commentId ] = data.markerName.split( ':' );\n\t*\n\t* \t\treturn {\n\t* \t\t\tclasses: [ 'comment', 'comment-' + commentType ],\n\t* \t\t\tattributes: { 'data-comment-id': commentId }\n\t* \t\t};\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* If a function is passed as the `config.view` parameter, it will be used to generate the highlight descriptor. The function\n\t* receives the `data` object and {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t* as the parameters and should return a\n\t* {@link module:engine/conversion/downcasthelpers~DowncastHighlightDescriptor highlight descriptor}.\n\t* The `data` object properties are passed from {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}.\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.model The name of the model marker (or model marker group) to convert.\n\t* @param config.view A highlight descriptor that will be used for highlighting or a function that takes the model marker data and\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as a parameters\n\t* and returns a highlight descriptor.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\tmarkerToHighlight(config) {\n\t\treturn this.add(downcastMarkerToHighlight(config));\n\t}\n\t/**\n\t* Model marker converter for data downcast.\n\t*\n\t* This conversion creates a representation for model marker boundaries in the view:\n\t*\n\t* * If the marker boundary is before or after a model element, a view attribute is set on a corresponding view element.\n\t* * In other cases, a view element with the specified tag name is inserted at the corresponding view position.\n\t*\n\t* Typically, the marker names use the `group:uniqueId:otherData` convention. For example: `comment:e34zfk9k2n459df53sjl34:zx32c`.\n\t* The default configuration for this conversion is that the first part is the `group` part and the rest of\n\t* the marker name becomes the `name` part.\n\t*\n\t* Tag and attribute names and values are generated from the marker name:\n\t*\n\t* * The templates for attributes are `data-[group]-start-before=\"[name]\"`, `data-[group]-start-after=\"[name]\"`,\n\t* `data-[group]-end-before=\"[name]\"` and `data-[group]-end-after=\"[name]\"`.\n\t* * The templates for view elements are `<[group]-start name=\"[name]\">` and `<[group]-end name=\"[name]\">`.\n\t*\n\t* Attributes mark whether the given marker's start or end boundary is before or after the given element.\n\t* The `data-[group]-start-before` and `data-[group]-end-after` attributes are favored.\n\t* The other two are used when the former two cannot be used.\n\t*\n\t* The conversion configuration can take a function that will generate different group and name parts.\n\t* If such a function is set as the `config.view` parameter, it is passed a marker name and it is expected to return an object with two\n\t* properties: `group` and `name`. If the function returns a falsy value, the conversion will not take place.\n\t*\n\t* Basic usage:\n\t*\n\t* ```ts\n\t* // Using the default conversion.\n\t* // In this case, all markers with names starting with 'comment:' will be converted.\n\t* // The `group` parameter will be set to `comment`.\n\t* // The `name` parameter will be the rest of the marker name (without the `:`).\n\t* editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t* \tmodel: 'comment'\n\t* } );\n\t* ```\n\t*\n\t* An example of a view that may be generated by this conversion (assuming a marker with the name `comment:commentId:uid` marked\n\t* by `[]`):\n\t*\n\t* ```\n\t* // Model:\n\t* <paragraph>Foo[bar</paragraph>\n\t* <imageBlock src=\"abc.jpg\"></imageBlock>]\n\t*\n\t* // View:\n\t* <p>Foo<comment-start name=\"commentId:uid\"></comment-start>bar</p>\n\t* <figure data-comment-end-after=\"commentId:uid\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t* ```\n\t*\n\t* In the example above, the comment starts before \"bar\" and ends after the image.\n\t*\n\t* If the `name` part is empty, the following view may be generated:\n\t*\n\t* ```html\n\t* <p>Foo <myMarker-start></myMarker-start>bar</p>\n\t* <figure data-myMarker-end-after=\"\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t* ```\n\t*\n\t* **Note:** A situation where some markers have the `name` part and some do not, is incorrect and should be avoided.\n\t*\n\t* Examples where `data-group-start-after` and `data-group-end-before` are used:\n\t*\n\t* ```\n\t* // Model:\n\t* <blockQuote>[]<paragraph>Foo</paragraph></blockQuote>\n\t*\n\t* // View:\n\t* <blockquote><p data-group-end-before=\"name\" data-group-start-before=\"name\">Foo</p></blockquote>\n\t* ```\n\t*\n\t* Similarly, when a marker is collapsed after the last element:\n\t*\n\t* ```\n\t* // Model:\n\t* <blockQuote><paragraph>Foo</paragraph>[]</blockQuote>\n\t*\n\t* // View:\n\t* <blockquote><p data-group-end-after=\"name\" data-group-start-after=\"name\">Foo</p></blockquote>\n\t* ```\n\t*\n\t* When there are multiple markers from the same group stored in the same attribute of the same element, their\n\t* name parts are put together in the attribute value, for example: `data-group-start-before=\"name1,name2,name3\"`.\n\t*\n\t* Other examples of usage:\n\t*\n\t* ```ts\n\t* // Using a custom function which is the same as the default conversion:\n\t* editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t* \tmodel: 'comment',\n\t* \tview: markerName => ( {\n\t* \t\tgroup: 'comment',\n\t* \t\tname: markerName.substr( 8 ) // Removes 'comment:' part.\n\t* \t} )\n\t* } );\n\t*\n\t* // Using the converter priority:\n\t* editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t* \tmodel: 'comment',\n\t* \tview: markerName => ( {\n\t* \t\tgroup: 'comment',\n\t* \t\tname: markerName.substr( 8 ) // Removes 'comment:' part.\n\t* \t} ),\n\t* \tconverterPriority: 'high'\n\t* } );\n\t* ```\n\t*\n\t* This kind of conversion is useful for saving data into the database, so it should be used in the data conversion pipeline.\n\t*\n\t* See the {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} API guide to learn how to\n\t* add a converter to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.model The name of the model marker (or the model marker group) to convert.\n\t* @param config.view A function that takes the model marker name and\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as the parameters\n\t* and returns an object with the `group` and `name` properties.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\tmarkerToData(config) {\n\t\treturn this.add(downcastMarkerToData(config));\n\t}\n};\n/**\n* Function factory that creates a default downcast converter for text insertion changes.\n*\n* The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n* {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n*\n* ```ts\n* modelDispatcher.on( 'insert:$text', insertText() );\n* ```\n*\n* @returns Insert text event converter.\n* @internal\n*/\nfunction insertText() {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!conversionApi.consumable.consume(data.item, evt.name)) return;\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition(data.range.start);\n\t\tconst viewText = viewWriter.createText(data.item.data);\n\t\tviewWriter.insert(viewPosition, viewText);\n\t};\n}\n/**\n* Function factory that creates a default downcast converter for triggering attributes and children conversion.\n*\n* @returns The converter.\n* @internal\n*/\nfunction insertAttributesAndChildren() {\n\treturn (evt, data, conversionApi) => {\n\t\tconversionApi.convertAttributes(data.item);\n\t\tif (!data.reconversion && data.item.is(\"element\") && !data.item.isEmpty) conversionApi.convertChildren(data.item);\n\t};\n}\n/**\n* Function factory that creates a default downcast converter for node remove changes.\n*\n* ```ts\n* modelDispatcher.on( 'remove', remove() );\n* ```\n*\n* @returns Remove event converter.\n* @internal\n*/\nfunction remove() {\n\treturn (evt, data, conversionApi) => {\n\t\tif (data.reconversion) return;\n\t\tconst viewStart = conversionApi.mapper.toViewPosition(data.position);\n\t\tconst modelEnd = data.position.getShiftedBy(data.length);\n\t\tconst viewEnd = conversionApi.mapper.toViewPosition(modelEnd, { isPhantom: true });\n\t\tremoveRangeAndUnbind(conversionApi.writer.createRange(viewStart, viewEnd).getTrimmed(), conversionApi);\n\t};\n}\n/**\n* Creates a `<span>` {@link module:engine/view/attributeelement~ViewAttributeElement view attribute element} from the information\n* provided by the {@link module:engine/conversion/downcasthelpers~DowncastHighlightDescriptor highlight descriptor} object. If the priority\n* is not provided in the descriptor, the default priority will be used.\n*\n* @internal\n*/\nfunction createViewElementFromDowncastHighlightDescriptor(writer, descriptor) {\n\tconst viewElement = writer.createAttributeElement(\"span\", descriptor.attributes);\n\tif (descriptor.classes) viewElement._addClass(descriptor.classes);\n\tif (typeof descriptor.priority === \"number\") viewElement._priority = descriptor.priority;\n\tviewElement._id = descriptor.id;\n\treturn viewElement;\n}\n/**\n* Function factory that creates a converter which converts a non-collapsed\n* {@link module:engine/model/selection~ModelSelection model selection}\n* to a {@link module:engine/view/documentselection~ViewDocumentSelection view selection}. The converter consumes appropriate\n* value from the `consumable` object and maps model positions from the selection to view positions.\n*\n* ```ts\n* modelDispatcher.on( 'selection', convertRangeSelection() );\n* ```\n*\n* @returns Selection converter.\n* @internal\n*/\nfunction convertRangeSelection() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst selection = data.selection;\n\t\tif (selection.isCollapsed) return;\n\t\tif (!conversionApi.consumable.consume(selection, \"selection\")) return;\n\t\tconst viewRanges = [];\n\t\tfor (const range of selection.getRanges()) viewRanges.push(conversionApi.mapper.toViewRange(range));\n\t\tconversionApi.writer.setSelection(viewRanges, { backward: selection.isBackward });\n\t};\n}\n/**\n* Function factory that creates a converter which converts a collapsed\n* {@link module:engine/model/selection~ModelSelection model selection} to\n* a {@link module:engine/view/documentselection~ViewDocumentSelection view selection}. The converter consumes appropriate\n* value from the `consumable` object, maps the model selection position to the view position and breaks\n* {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements} at the selection position.\n*\n* ```ts\n* modelDispatcher.on( 'selection', convertCollapsedSelection() );\n* ```\n*\n* An example of the view state before and after converting the collapsed selection:\n*\n* ```\n* <p><strong>f^oo<strong>bar</p>\n* -> <p><strong>f</strong>^<strong>oo</strong>bar</p>\n* ```\n*\n* By breaking attribute elements like `<strong>`, the selection is in a correct element. Then, when the selection attribute is\n* converted, broken attributes might be merged again, or the position where the selection is may be wrapped\n* with different, appropriate attribute elements.\n*\n* See also {@link module:engine/conversion/downcasthelpers~cleanSelection} which does a clean-up\n* by merging attributes.\n*\n* @returns Selection converter.\n* @internal\n*/\nfunction convertCollapsedSelection() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst selection = data.selection;\n\t\tif (!selection.isCollapsed) return;\n\t\tif (!conversionApi.consumable.consume(selection, \"selection\")) return;\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst modelPosition = selection.getFirstPosition();\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition(modelPosition);\n\t\tconst brokenPosition = viewWriter.breakAttributes(viewPosition);\n\t\tviewWriter.setSelection(brokenPosition);\n\t};\n}\n/**\n* Function factory that creates a converter which cleans artifacts after the previous\n* {@link module:engine/model/selection~ModelSelection model selection} conversion. It removes all empty\n* {@link module:engine/view/attributeelement~ViewAttributeElement view attribute elements} and merges\n* sibling attributes at all start and end positions of all ranges.\n*\n* ```\n* <p><strong>^</strong></p>\n* -> <p>^</p>\n*\n* <p><strong>foo</strong>^<strong>bar</strong>bar</p>\n* -> <p><strong>foo^bar<strong>bar</p>\n*\n* <p><strong>foo</strong><em>^</em><strong>bar</strong>bar</p>\n* -> <p><strong>foo^bar<strong>bar</p>\n* ```\n*\n* This listener should be assigned before any converter for the new selection:\n*\n* ```ts\n* modelDispatcher.on( 'cleanSelection', cleanSelection() );\n* ```\n*\n* See {@link module:engine/conversion/downcasthelpers~convertCollapsedSelection}\n* which does the opposite by breaking attributes in the selection position.\n*\n* @returns Selection converter.\n* @internal\n*/\nfunction cleanSelection() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewSelection = viewWriter.document.selection;\n\t\tfor (const range of viewSelection.getRanges()) if (range.isCollapsed) {\n\t\t\tif (range.end.parent.isAttached()) conversionApi.writer.mergeAttributes(range.start);\n\t\t}\n\t\tviewWriter.setSelection(null);\n\t};\n}\n/**\n* Function factory that creates a converter which converts the set/change/remove attribute changes from the model to the view.\n* It can also be used to convert selection attributes. In that case, an empty attribute element will be created and the\n* selection will be put inside it.\n*\n* Attributes from the model are converted to a view element that will be wrapping these view nodes that are bound to\n* model elements having the given attribute. This is useful for attributes like `bold` that may be set on text nodes in the model\n* but are represented as an element in the view:\n*\n* ```\n* [paragraph] MODEL ====> VIEW <p>\n* \t|- a {bold: true} |- <b>\n* \t|- b {bold: true} | |- ab\n* \t|- c |- c\n* \t```\n*\n* Passed `Function` will be provided with the attribute value and then all the parameters of the\n* {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute` event}.\n* It is expected that the function returns an {@link module:engine/view/element~ViewElement}.\n* The result of the function will be the wrapping element.\n* When the provided `Function` does not return any element, no conversion will take place.\n*\n* The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n* {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n*\n* ```ts\n* modelDispatcher.on( 'attribute:bold', wrap( ( modelAttributeValue, { writer } ) => {\n* \treturn writer.createAttributeElement( 'strong' );\n* } );\n* ```\n*\n* @internal\n* @param elementCreator Function returning a view element that will be used for wrapping.\n* @returns Set/change attribute converter.\n*/\nfunction wrap(elementCreator) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!conversionApi.consumable.test(data.item, evt.name)) return;\n\t\tconst oldViewElement = elementCreator(data.attributeOldValue, conversionApi, data);\n\t\tconst newViewElement = elementCreator(data.attributeNewValue, conversionApi, data);\n\t\tif (!oldViewElement && !newViewElement) return;\n\t\tconversionApi.consumable.consume(data.item, evt.name);\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewSelection = viewWriter.document.selection;\n\t\tif (data.item instanceof ModelSelection || data.item instanceof ModelDocumentSelection) viewWriter.wrap(viewSelection.getFirstRange(), newViewElement);\n\t\telse {\n\t\t\tlet viewRange = conversionApi.mapper.toViewRange(data.range);\n\t\t\tif (data.attributeOldValue !== null && oldViewElement) viewRange = viewWriter.unwrap(viewRange, oldViewElement);\n\t\t\tif (data.attributeNewValue !== null && newViewElement) viewWriter.wrap(viewRange, newViewElement);\n\t\t}\n\t};\n}\n/**\n* Function factory that creates a converter which converts node insertion changes from the model to the view.\n* The function passed will be provided with all the parameters of the dispatcher's\n* {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert` event}.\n* It is expected that the function returns an {@link module:engine/view/element~ViewElement}.\n* The result of the function will be inserted into the view.\n*\n* The converter automatically consumes the corresponding value from the consumables list and binds the model and view elements.\n*\n* ```ts\n* downcastDispatcher.on(\n* \t'insert:myElem',\n* \tinsertElement( ( modelItem, { writer } ) => {\n* \t\tconst text = writer.createText( 'myText' );\n* \t\tconst myElem = writer.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );\n*\n* \t\t// Do something fancy with `myElem` using `modelItem` or other parameters.\n*\n* \t\treturn myElem;\n* \t}\n* ) );\n* ```\n*\n* @internal\n* @param elementCreator Function returning a view element, which will be inserted.\n* @param consumer Function defining element consumption process.\n* By default this function just consume passed item insertion.\n* @returns Insert element event converter.\n*/\nfunction insertElement(elementCreator, consumer = defaultConsumer) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!consumer(data.item, conversionApi.consumable, { preflight: true })) return;\n\t\tconst viewElement = elementCreator(data.item, conversionApi, data);\n\t\tif (!viewElement) return;\n\t\tconsumer(data.item, conversionApi.consumable);\n\t\tconst viewPosition = data.reconversion && removeElementAndUnbind(data.item, conversionApi) || conversionApi.mapper.toViewPosition(data.range.start);\n\t\tconversionApi.mapper.bindElements(data.item, viewElement);\n\t\tconversionApi.writer.insert(viewPosition, viewElement);\n\t\tconversionApi.convertAttributes(data.item);\n\t\treinsertOrConvertNodes(viewElement, data.item.getChildren(), conversionApi, { reconversion: data.reconversion });\n\t};\n}\n/**\n* Function factory that creates a converter which converts a single model node insertion to a view structure.\n*\n* It is expected that the passed element creator function returns an {@link module:engine/view/element~ViewElement} with attached slots\n* created with `writer.createSlot()` to indicate where child nodes should be converted.\n*\n* @see module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n*\n* @internal\n* @param elementCreator Function returning a view structure, which will be inserted.\n* @param consumer A callback that is expected to consume all the consumables\n* that were used by the element creator.\n* @returns Insert element event converter.\n*/\nfunction insertStructure(elementCreator, consumer) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!consumer(data.item, conversionApi.consumable, { preflight: true })) return;\n\t\tconst slotsMap = /* @__PURE__ */ new Map();\n\t\tconversionApi.writer._registerSlotFactory(createSlotFactory(data.item, slotsMap, conversionApi));\n\t\tconst viewElement = elementCreator(data.item, conversionApi, data);\n\t\tconversionApi.writer._clearSlotFactory();\n\t\tif (!viewElement) return;\n\t\tvalidateSlotsChildren(data.item, slotsMap, conversionApi);\n\t\tconsumer(data.item, conversionApi.consumable);\n\t\tconst viewPosition = data.reconversion && removeElementAndUnbind(data.item, conversionApi) || conversionApi.mapper.toViewPosition(data.range.start);\n\t\tconversionApi.mapper.bindElements(data.item, viewElement);\n\t\tconversionApi.writer.insert(viewPosition, viewElement);\n\t\tconversionApi.convertAttributes(data.item);\n\t\tfillSlots(viewElement, slotsMap, conversionApi, { reconversion: data.reconversion });\n\t};\n}\n/**\n* Function factory that creates a converter which converts marker adding change to the\n* {@link module:engine/view/uielement~ViewUIElement view UI element}.\n*\n* The view UI element that will be added to the view depends on the passed parameter. See {@link ~insertElement}.\n* In case of a non-collapsed range, the UI element will not wrap nodes but separate elements will be placed at the beginning\n* and at the end of the range.\n*\n* This converter binds created UI elements with the marker name using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.\n*\n* @internal\n* @param elementCreator A view UI element or a function returning the view element that will be inserted.\n* @returns Insert element event converter.\n*/\nfunction insertUIElement(elementCreator) {\n\treturn (evt, data, conversionApi) => {\n\t\tdata.isOpening = true;\n\t\tconst viewStartElement = elementCreator(data, conversionApi);\n\t\tdata.isOpening = false;\n\t\tconst viewEndElement = elementCreator(data, conversionApi);\n\t\tif (!viewStartElement || !viewEndElement) return;\n\t\tconst { markerRange, markerName } = data;\n\t\tif (markerRange.isCollapsed && !conversionApi.consumable.consume(markerRange, evt.name)) return;\n\t\tfor (const value of markerRange) if (!conversionApi.consumable.consume(value.item, evt.name)) return;\n\t\tconst mapper = conversionApi.mapper;\n\t\tconst viewWriter = conversionApi.writer;\n\t\tviewWriter.setCustomProperty(\"markerBoundaryType\", \"start\", viewStartElement);\n\t\tviewWriter.setCustomProperty(\"markerBoundaryName\", markerName, viewStartElement);\n\t\tviewWriter.setCustomProperty(\"markerBoundaryType\", \"end\", viewEndElement);\n\t\tviewWriter.setCustomProperty(\"markerBoundaryName\", markerName, viewEndElement);\n\t\tconst getBoundaryModelPosition = (name, type) => {\n\t\t\tconst elements = mapper.markerNameToElements(name);\n\t\t\tif (elements) {\n\t\t\t\tfor (const el of elements) if (el.getCustomProperty(\"markerBoundaryType\") === type) return mapper.toModelPosition(viewWriter.createPositionBefore(el));\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\t\tif (!markerRange.isCollapsed) {\n\t\t\tconst endViewPosition = mapper.toViewPosition(markerRange.end).getLastMatchingPosition(({ item }) => {\n\t\t\t\tif (!item.is(\"uiElement\") || item.getCustomProperty(\"markerBoundaryType\") !== \"end\") return false;\n\t\t\t\tconst existingName = item.getCustomProperty(\"markerBoundaryName\");\n\t\t\t\tconst existingStartPos = getBoundaryModelPosition(existingName, \"start\");\n\t\t\t\tif (!existingStartPos) return false;\n\t\t\t\tconst cmp = existingStartPos.compareWith(markerRange.start);\n\t\t\t\tif (cmp === \"same\") return existingName.localeCompare(markerName) > 0;\n\t\t\t\treturn cmp === \"after\";\n\t\t\t});\n\t\t\tviewWriter.insert(endViewPosition, viewEndElement);\n\t\t\tmapper.bindElementToMarker(viewEndElement, markerName);\n\t\t}\n\t\tconst startViewPosition = mapper.toViewPosition(markerRange.start).getLastMatchingPosition(({ item }) => {\n\t\t\tif (!item.is(\"uiElement\")) return false;\n\t\t\tconst boundaryType = item.getCustomProperty(\"markerBoundaryType\");\n\t\t\tif (!boundaryType) return false;\n\t\t\tif (boundaryType === \"end\") return true;\n\t\t\tconst existingName = item.getCustomProperty(\"markerBoundaryName\");\n\t\t\tconst existingEndPos = getBoundaryModelPosition(existingName, \"end\");\n\t\t\tif (!existingEndPos) return markerRange.isCollapsed;\n\t\t\tif (markerRange.isCollapsed) return true;\n\t\t\tconst cmp = existingEndPos.compareWith(markerRange.end);\n\t\t\tif (cmp === \"same\") return existingName.localeCompare(markerName) < 0;\n\t\t\treturn cmp === \"after\";\n\t\t});\n\t\tviewWriter.insert(startViewPosition, viewStartElement);\n\t\tmapper.bindElementToMarker(viewStartElement, markerName);\n\t\tevt.stop();\n\t};\n}\n/**\n* Removes given view range content and unbinds removed elements.\n*/\nfunction removeRangeAndUnbind(viewRange, conversionApi) {\n\tconst removed = conversionApi.writer.remove(viewRange);\n\tfor (const child of conversionApi.writer.createRangeIn(removed).getItems()) conversionApi.mapper.unbindViewElement(child, { defer: true });\n\treturn viewRange.start;\n}\n/**\n* Removes view element for given model element and unbinds removed view elements.\n*/\nfunction removeElementAndUnbind(modelElement, conversionApi) {\n\tconst viewElement = conversionApi.mapper.toViewElement(modelElement);\n\treturn viewElement && removeRangeAndUnbind(conversionApi.writer.createRangeOn(viewElement), conversionApi);\n}\n/**\n* Function factory that returns a default downcast converter for removing a {@link module:engine/view/uielement~ViewUIElement UI element}\n* based on marker remove change.\n*\n* This converter unbinds elements from the marker name.\n*\n* @returns Removed UI element converter.\n*/\nfunction removeUIElement() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst elements = conversionApi.mapper.markerNameToElements(data.markerName);\n\t\tif (!elements) return;\n\t\tfor (const element of elements) {\n\t\t\tconversionApi.mapper.unbindElementFromMarkerName(element, data.markerName);\n\t\t\tconversionApi.writer.clear(conversionApi.writer.createRangeOn(element), element);\n\t\t}\n\t\tconversionApi.writer.clearClonedElementsGroup(data.markerName);\n\t\tevt.stop();\n\t};\n}\n/**\n* Function factory that creates a default converter for model markers.\n*\n* See {@link DowncastHelpers#markerToData} for more information what type of view is generated.\n*\n* This converter binds created UI elements and affected view elements with the marker name\n* using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.\n*\n* @returns Add marker converter.\n*/\nfunction insertMarkerData(viewCreator) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst viewMarkerData = viewCreator(data.markerName, conversionApi);\n\t\tif (!viewMarkerData) return;\n\t\tconst markerRange = data.markerRange;\n\t\tif (!conversionApi.consumable.consume(markerRange, evt.name)) return;\n\t\thandleMarkerBoundary(markerRange, false, conversionApi, data, viewMarkerData);\n\t\thandleMarkerBoundary(markerRange, true, conversionApi, data, viewMarkerData);\n\t\tevt.stop();\n\t};\n}\n/**\n* Helper function for `insertMarkerData()` that marks a marker boundary at the beginning or end of given `range`.\n*/\nfunction handleMarkerBoundary(range, isStart, conversionApi, data, viewMarkerData) {\n\tconst modelPosition = isStart ? range.start : range.end;\n\tconst elementAfter = modelPosition.nodeAfter && modelPosition.nodeAfter.is(\"element\") ? modelPosition.nodeAfter : null;\n\tconst elementBefore = modelPosition.nodeBefore && modelPosition.nodeBefore.is(\"element\") ? modelPosition.nodeBefore : null;\n\tif (elementAfter || elementBefore) {\n\t\tlet modelElement;\n\t\tlet isBefore;\n\t\tif (isStart && elementAfter || !isStart && !elementBefore) {\n\t\t\tmodelElement = elementAfter;\n\t\t\tisBefore = true;\n\t\t} else {\n\t\t\tmodelElement = elementBefore;\n\t\t\tisBefore = false;\n\t\t}\n\t\tconst viewElement = conversionApi.mapper.toViewElement(modelElement);\n\t\tif (viewElement) {\n\t\t\tinsertMarkerAsAttribute(viewElement, isStart, isBefore, conversionApi, data, viewMarkerData);\n\t\t\treturn;\n\t\t}\n\t}\n\tinsertMarkerAsElement(conversionApi.mapper.toViewPosition(modelPosition), isStart, conversionApi, data, viewMarkerData);\n}\n/**\n* Helper function for `insertMarkerData()` that marks a marker boundary in the view as an attribute on a view element.\n*/\nfunction insertMarkerAsAttribute(viewElement, isStart, isBefore, conversionApi, data, viewMarkerData) {\n\tconst attributeName = `data-${viewMarkerData.group}-${isStart ? \"start\" : \"end\"}-${isBefore ? \"before\" : \"after\"}`;\n\tconst markerNames = viewElement.hasAttribute(attributeName) ? viewElement.getAttribute(attributeName).split(\",\") : [];\n\tmarkerNames.unshift(viewMarkerData.name);\n\tconversionApi.writer.setAttribute(attributeName, markerNames.join(\",\"), viewElement);\n\tconversionApi.mapper.bindElementToMarker(viewElement, data.markerName);\n}\n/**\n* Helper function for `insertMarkerData()` that marks a marker boundary in the view as a separate view ui element.\n*/\nfunction insertMarkerAsElement(position, isStart, conversionApi, data, viewMarkerData) {\n\tconst viewElementName = `${viewMarkerData.group}-${isStart ? \"start\" : \"end\"}`;\n\tconst attrs = viewMarkerData.name ? { \"name\": viewMarkerData.name } : null;\n\tconst viewElement = conversionApi.writer.createUIElement(viewElementName, attrs);\n\tconversionApi.writer.insert(position, viewElement);\n\tconversionApi.mapper.bindElementToMarker(viewElement, data.markerName);\n}\n/**\n* Function factory that creates a converter for removing a model marker data added by the {@link #insertMarkerData} converter.\n*\n* @returns Remove marker converter.\n*/\nfunction removeMarkerData(viewCreator) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst viewData = viewCreator(data.markerName, conversionApi);\n\t\tif (!viewData) return;\n\t\tconst elements = conversionApi.mapper.markerNameToElements(data.markerName);\n\t\tif (!elements) return;\n\t\tfor (const element of elements) {\n\t\t\tconversionApi.mapper.unbindElementFromMarkerName(element, data.markerName);\n\t\t\tif (element.is(\"containerElement\")) {\n\t\t\t\tremoveMarkerFromAttribute(`data-${viewData.group}-start-before`, element);\n\t\t\t\tremoveMarkerFromAttribute(`data-${viewData.group}-start-after`, element);\n\t\t\t\tremoveMarkerFromAttribute(`data-${viewData.group}-end-before`, element);\n\t\t\t\tremoveMarkerFromAttribute(`data-${viewData.group}-end-after`, element);\n\t\t\t} else conversionApi.writer.clear(conversionApi.writer.createRangeOn(element), element);\n\t\t}\n\t\tconversionApi.writer.clearClonedElementsGroup(data.markerName);\n\t\tevt.stop();\n\t\tfunction removeMarkerFromAttribute(attributeName, element) {\n\t\t\tif (element.hasAttribute(attributeName)) {\n\t\t\t\tconst markerNames = new Set(element.getAttribute(attributeName).split(\",\"));\n\t\t\t\tmarkerNames.delete(viewData.name);\n\t\t\t\tif (markerNames.size == 0) conversionApi.writer.removeAttribute(attributeName, element);\n\t\t\t\telse conversionApi.writer.setAttribute(attributeName, Array.from(markerNames).join(\",\"), element);\n\t\t\t}\n\t\t}\n\t};\n}\n/**\n* Function factory that creates a converter which converts the set/change/remove attribute changes from the model to the view.\n*\n* Attributes from the model are converted to the view element attributes in the view. You may provide a custom function to generate\n* a key-value attribute pair to add/change/remove. If not provided, model attributes will be converted to view element\n* attributes on a one-to-one basis.\n*\n* *Note:** The provided attribute creator should always return the same `key` for a given attribute from the model.\n*\n* The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n* {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n*\n* ```ts\n* modelDispatcher.on( 'attribute:customAttr:myElem', changeAttribute( ( value, data ) => {\n* \t// Change attribute key from `customAttr` to `class` in the view.\n* \tconst key = 'class';\n* \tlet value = data.attributeNewValue;\n*\n* \t// Force attribute value to 'empty' if the model element is empty.\n* \tif ( data.item.childCount === 0 ) {\n* \t\tvalue = 'empty';\n* \t}\n*\n* \t// Return the key-value pair.\n* \treturn { key, value };\n* } ) );\n* ```\n*\n* @param attributeCreator Function returning an object with two properties: `key` and `value`, which\n* represent the attribute key and attribute value to be set on a {@link module:engine/view/element~ViewElement view element}.\n* The function is passed the model attribute value as the first parameter and additional data about the change as the second parameter.\n* @returns Set/change attribute converter.\n*/\nfunction changeAttribute(attributeCreator) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!conversionApi.consumable.test(data.item, evt.name)) return;\n\t\tconst oldAttribute = attributeCreator(data.attributeOldValue, conversionApi, data);\n\t\tconst newAttribute = attributeCreator(data.attributeNewValue, conversionApi, data);\n\t\tif (!oldAttribute && !newAttribute) return;\n\t\tconversionApi.consumable.consume(data.item, evt.name);\n\t\tconst viewElement = conversionApi.mapper.toViewElement(data.item);\n\t\tconst viewWriter = conversionApi.writer;\n\t\tif (!viewElement)\n /**\n\t\t* This error occurs when a {@link module:engine/model/textproxy~ModelTextProxy text node's} attribute is to be downcasted\n\t\t* by an {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `Attribute to Attribute converter`}.\n\t\t* In most cases it is caused by converters misconfiguration when only \"generic\" converter is defined:\n\t\t*\n\t\t* ```ts\n\t\t* editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t\t* \tmodel: 'attribute-name',\n\t\t* \tview: 'attribute-name'\n\t\t* } ) );\n\t\t* ```\n\t\t*\n\t\t* and given attribute is used on text node, for example:\n\t\t*\n\t\t* ```ts\n\t\t* model.change( writer => {\n\t\t* \twriter.insertText( 'Foo', { 'attribute-name': 'bar' }, parent, 0 );\n\t\t* } );\n\t\t* ```\n\t\t*\n\t\t* In such cases, to convert the same attribute for both {@link module:engine/model/element~ModelElement}\n\t\t* and {@link module:engine/model/textproxy~ModelTextProxy `Text`} nodes, text specific\n\t\t* {@link module:engine/conversion/conversion~Conversion#attributeToElement `Attribute to Element converter`}\n\t\t* with higher {@link module:utils/priorities~PriorityString priority} must also be defined:\n\t\t*\n\t\t* ```ts\n\t\t* editor.conversion.for( 'downcast' ).attributeToElement( {\n\t\t* \tmodel: {\n\t\t* \t\tkey: 'attribute-name',\n\t\t* \t\tname: '$text'\n\t\t* \t},\n\t\t* \tview: ( value, { writer } ) => {\n\t\t* \t\treturn writer.createAttributeElement( 'span', { 'attribute-name': value } );\n\t\t* \t},\n\t\t* \tconverterPriority: 'high'\n\t\t* } ) );\n\t\t* ```\n\t\t*\n\t\t* @error conversion-attribute-to-attribute-on-text\n\t\t* @param {object} data The conversion data.\n\t\t*/\n\t\tthrow new CKEditorError(\"conversion-attribute-to-attribute-on-text\", conversionApi.dispatcher, data);\n\t\tif (data.attributeOldValue !== null && oldAttribute) {\n\t\t\tlet value = oldAttribute.value;\n\t\t\tif (oldAttribute.key == \"style\") if (typeof oldAttribute.value == \"string\") value = new StylesMap(viewWriter.document.stylesProcessor).setTo(oldAttribute.value).getStylesEntries().map(([key]) => key);\n\t\t\telse value = Object.keys(oldAttribute.value);\n\t\t\tviewWriter.removeAttribute(oldAttribute.key, value, viewElement);\n\t\t}\n\t\tif (data.attributeNewValue !== null && newAttribute) {\n\t\t\tlet value = newAttribute.value;\n\t\t\tif (newAttribute.key == \"style\" && typeof newAttribute.value == \"string\") value = Object.fromEntries(new StylesMap(viewWriter.document.stylesProcessor).setTo(newAttribute.value).getStylesEntries());\n\t\t\tviewWriter.setAttribute(newAttribute.key, value, false, viewElement);\n\t\t}\n\t};\n}\n/**\n* Function factory that creates a converter which converts the text inside marker's range. The converter wraps the text with\n* {@link module:engine/view/attributeelement~ViewAttributeElement} created from the provided descriptor.\n* See {link module:engine/conversion/downcasthelpers~createViewElementFromDowncastHighlightDescriptor}.\n*\n* It can also be used to convert the selection that is inside a marker. In that case, an empty attribute element will be\n* created and the selection will be put inside it.\n*\n* If the highlight descriptor does not provide the `priority` property, `10` will be used.\n*\n* If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n*\n* This converter binds the created {@link module:engine/view/attributeelement~ViewAttributeElement attribute elemens} with the marker name\n* using the {@link module:engine/conversion/mapper~Mapper#bindElementToMarker} method.\n*/\nfunction highlightText(highlightDescriptor) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!data.item) return;\n\t\tif (!(data.item instanceof ModelSelection || data.item instanceof ModelDocumentSelection) && !data.item.is(\"$textProxy\")) return;\n\t\tconst descriptor = prepareDescriptor(highlightDescriptor, data, conversionApi);\n\t\tif (!descriptor) return;\n\t\tif (!conversionApi.consumable.consume(data.item, evt.name)) return;\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewElement = createViewElementFromDowncastHighlightDescriptor(viewWriter, descriptor);\n\t\tconst viewSelection = viewWriter.document.selection;\n\t\tif (data.item instanceof ModelSelection || data.item instanceof ModelDocumentSelection) viewWriter.wrap(viewSelection.getFirstRange(), viewElement);\n\t\telse {\n\t\t\tconst viewRange = conversionApi.mapper.toViewRange(data.range);\n\t\t\tconst rangeAfterWrap = viewWriter.wrap(viewRange, viewElement);\n\t\t\tfor (const element of rangeAfterWrap.getItems()) if (element.is(\"attributeElement\") && element.isSimilar(viewElement)) {\n\t\t\t\tconversionApi.mapper.bindElementToMarker(element, data.markerName);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n}\n/**\n* Converter function factory. It creates a function which applies the marker's highlight to an element inside the marker's range.\n*\n* The converter checks if an element has the `addHighlight` function stored as a\n* {@link module:engine/view/element~ViewElement#_setCustomProperty custom property} and, if so, uses it to apply the highlight.\n* In such case the converter will consume all element's children, assuming that they were handled by the element itself.\n*\n* When the `addHighlight` custom property is not present, the element is not converted in any special way.\n* This means that converters will proceed to convert the element's child nodes.\n*\n* If the highlight descriptor does not provide the `priority` property, `10` will be used.\n*\n* If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n*\n* This converter binds altered {@link module:engine/view/containerelement~ViewContainerElement container elements}\n* with the marker name using the {@link module:engine/conversion/mapper~Mapper#bindElementToMarker} method.\n*/\nfunction highlightElement(highlightDescriptor) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!data.item) return;\n\t\tif (!(data.item instanceof ModelElement)) return;\n\t\tconst descriptor = prepareDescriptor(highlightDescriptor, data, conversionApi);\n\t\tif (!descriptor) return;\n\t\tif (!conversionApi.consumable.test(data.item, evt.name)) return;\n\t\tconst viewElement = conversionApi.mapper.toViewElement(data.item);\n\t\tif (viewElement && viewElement.getCustomProperty(\"addHighlight\")) {\n\t\t\tconversionApi.consumable.consume(data.item, evt.name);\n\t\t\tfor (const value of ModelRange._createIn(data.item)) conversionApi.consumable.consume(value.item, evt.name);\n\t\t\tviewElement.getCustomProperty(\"addHighlight\")(viewElement, descriptor, conversionApi.writer);\n\t\t\tconversionApi.mapper.bindElementToMarker(viewElement, data.markerName);\n\t\t}\n\t};\n}\n/**\n* Function factory that creates a converter which converts the removing model marker to the view.\n*\n* Both text nodes and elements are handled by this converter but they are handled a bit differently.\n*\n* Text nodes are unwrapped using the {@link module:engine/view/attributeelement~ViewAttributeElement attribute element} created from the\n* provided highlight descriptor. See {link module:engine/conversion/downcasthelpers~DowncastHighlightDescriptor}.\n*\n* For elements, the converter checks if an element has the `removeHighlight` function stored as a\n* {@link module:engine/view/element~ViewElement#_setCustomProperty custom property}. If so, it uses it to remove the highlight.\n* In such case, the children of that element will not be converted.\n*\n* When `removeHighlight` is not present, the element is not converted in any special way.\n* The converter will proceed to convert the element's child nodes instead.\n*\n* If the highlight descriptor does not provide the `priority` property, `10` will be used.\n*\n* If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n*\n* This converter unbinds elements from the marker name.\n*/\nfunction removeHighlight(highlightDescriptor) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (data.markerRange.isCollapsed) return;\n\t\tconst descriptor = prepareDescriptor(highlightDescriptor, data, conversionApi);\n\t\tif (!descriptor) return;\n\t\tconst viewHighlightElement = createViewElementFromDowncastHighlightDescriptor(conversionApi.writer, descriptor);\n\t\tconst elements = conversionApi.mapper.markerNameToElements(data.markerName);\n\t\tif (!elements) return;\n\t\tfor (const element of elements) {\n\t\t\tconversionApi.mapper.unbindElementFromMarkerName(element, data.markerName);\n\t\t\tif (element.is(\"attributeElement\")) conversionApi.writer.unwrap(conversionApi.writer.createRangeOn(element), viewHighlightElement);\n\t\t\telse element.getCustomProperty(\"removeHighlight\")(element, descriptor.id, conversionApi.writer);\n\t\t}\n\t\tconversionApi.writer.clearClonedElementsGroup(data.markerName);\n\t\tevt.stop();\n\t};\n}\n/**\n* Model element to view element conversion helper.\n*\n* See {@link ~DowncastHelpers#elementToElement `.elementToElement()` downcast helper} for examples and config params description.\n*\n* @param config Conversion configuration.\n* @param config.model The description or a name of the model element to convert.\n* @param config.model.attributes List of attributes triggering element reconversion.\n* @param config.model.children Should reconvert element if the list of model child nodes changed.\n* @returns Conversion helper.\n*/\nfunction downcastElementToElement(config) {\n\tconst model = normalizeModelElementConfig(config.model);\n\tconst view = normalizeToElementConfig(config.view, \"container\");\n\tif (model.attributes.length) model.children = true;\n\treturn (dispatcher) => {\n\t\tdispatcher.on(`insert:${model.name}`, insertElement(view, createConsumer(model)), { priority: config.converterPriority || \"normal\" });\n\t\tif (model.children || model.attributes.length) dispatcher.on(\"reduceChanges\", createChangeReducer(model), { priority: \"low\" });\n\t};\n}\n/**\n* Model element to view structure conversion helper.\n*\n* See {@link ~DowncastHelpers#elementToStructure `.elementToStructure()` downcast helper} for examples and config params description.\n*\n* @param config Conversion configuration.\n* @returns Conversion helper.\n*/\nfunction downcastElementToStructure(config) {\n\tconst model = normalizeModelElementConfig(config.model);\n\tconst view = normalizeToElementConfig(config.view, \"container\");\n\tmodel.children = true;\n\treturn (dispatcher) => {\n\t\tif (dispatcher._conversionApi.schema.checkChild(model.name, \"$text\"))\n /**\n\t\t* This error occurs when a {@link module:engine/model/element~ModelElement model element} is downcasted\n\t\t* via {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure} helper but the element was\n\t\t* allowed to host `$text` by the {@link module:engine/model/schema~ModelSchema model schema}.\n\t\t*\n\t\t* For instance, this may be the result of `myElement` allowing the content of\n\t\t* {@glink framework/deep-dive/schema#generic-items `$block`} in its schema definition:\n\t\t*\n\t\t* ```ts\n\t\t* // Element definition in schema.\n\t\t* schema.register( 'myElement', {\n\t\t* \tallowContentOf: '$block',\n\t\t*\n\t\t* \t// ...\n\t\t* } );\n\t\t*\n\t\t* // ...\n\t\t*\n\t\t* // Conversion of myElement with the use of elementToStructure().\n\t\t* editor.conversion.for( 'downcast' ).elementToStructure( {\n\t\t* \tmodel: 'myElement',\n\t\t* \tview: ( modelElement, { writer } ) => {\n\t\t* \t\t// ...\n\t\t* \t}\n\t\t* } );\n\t\t* ```\n\t\t*\n\t\t* In such case, {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`} helper\n\t\t* can be used instead to get around this problem:\n\t\t*\n\t\t* ```ts\n\t\t* editor.conversion.for( 'downcast' ).elementToElement( {\n\t\t* \tmodel: 'myElement',\n\t\t* \tview: ( modelElement, { writer } ) => {\n\t\t* \t\t// ...\n\t\t* \t}\n\t\t* } );\n\t\t* ```\n\t\t*\n\t\t* @error conversion-element-to-structure-disallowed-text\n\t\t* @param {string} elementName The name of the element the structure is to be created for.\n\t\t*/\n\t\tthrow new CKEditorError(\"conversion-element-to-structure-disallowed-text\", dispatcher, { elementName: model.name });\n\t\tdispatcher.on(`insert:${model.name}`, insertStructure(view, createConsumer(model)), { priority: config.converterPriority || \"normal\" });\n\t\tdispatcher.on(\"reduceChanges\", createChangeReducer(model), { priority: \"low\" });\n\t};\n}\n/**\n* Model attribute to view element conversion helper.\n*\n* See {@link ~DowncastHelpers#attributeToElement `.attributeToElement()` downcast helper} for examples.\n*\n* @param config Conversion configuration.\n* @param config.model The key of the attribute to convert from or a `{ key, values }` object. `values` is an array\n* of `String`s with possible values if the model attribute is an enumerable.\n* @param config.view A view element definition or a function that takes the model attribute value and\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter view downcast writer} as parameters and returns a view attribute element.\n* If `config.model.values` is given, `config.view` should be an object assigning values from `config.model.values` to view element\n* definitions or functions.\n* @param config.converterPriority Converter priority.\n* @returns Conversion helper.\n*/\nfunction downcastAttributeToElement(config) {\n\tconfig = cloneDeep(config);\n\tlet model = config.model;\n\tif (typeof model == \"string\") model = { key: model };\n\tlet eventName = `attribute:${model.key}`;\n\tif (model.name) eventName += \":\" + model.name;\n\tif (model.values) for (const modelValue of model.values) config.view[modelValue] = normalizeToElementConfig(config.view[modelValue], \"attribute\");\n\telse config.view = normalizeToElementConfig(config.view, \"attribute\");\n\tconst elementCreator = getFromAttributeCreator(config);\n\treturn (dispatcher) => {\n\t\tdispatcher.on(eventName, wrap(elementCreator), { priority: config.converterPriority || \"normal\" });\n\t};\n}\n/**\n* Model attribute to view attribute conversion helper.\n*\n* See {@link ~DowncastHelpers#attributeToAttribute `.attributeToAttribute()` downcast helper} for examples.\n*\n* @param config Conversion configuration.\n* @param config.model The key of the attribute to convert from or a `{ key, values, [ name ] }` object describing\n* the attribute key, possible values and, optionally, an element name to convert from.\n* @param config.view A view attribute key, or a `{ key, value }` object or a function that takes the model attribute value and returns\n* a `{ key, value }` object.\n* If `key` is `'class'`, `value` can be a `String` or an array of `String`s. If `key` is `'style'`, `value` is an object with\n* key-value pairs. In other cases, `value` is a `String`.\n* If `config.model.values` is set, `config.view` should be an object assigning values from `config.model.values` to\n* `{ key, value }` objects or a functions.\n* @param config.converterPriority Converter priority.\n* @returns Conversion helper.\n*/\nfunction downcastAttributeToAttribute(config) {\n\tconfig = cloneDeep(config);\n\tlet model = config.model;\n\tif (typeof model == \"string\") model = { key: model };\n\tlet eventName = `attribute:${model.key}`;\n\tif (model.name) eventName += \":\" + model.name;\n\tif (model.values) for (const modelValue of model.values) config.view[modelValue] = normalizeToAttributeConfig(config.view[modelValue]);\n\telse config.view = normalizeToAttributeConfig(config.view);\n\tconst elementCreator = getFromAttributeCreator(config);\n\treturn (dispatcher) => {\n\t\tdispatcher.on(eventName, changeAttribute(elementCreator), { priority: config.converterPriority || \"normal\" });\n\t};\n}\n/**\n* Model marker to view element conversion helper.\n*\n* See {@link ~DowncastHelpers#markerToElement `.markerToElement()` downcast helper} for examples.\n*\n* @param config Conversion configuration.\n* @param config.model The name of the model marker (or model marker group) to convert.\n* @param config.view A view element definition or a function that takes the model marker data as a parameter and returns a view UI element.\n* @param config.converterPriority Converter priority.\n* @returns Conversion helper.\n*/\nfunction downcastMarkerToElement(config) {\n\tconst view = normalizeToElementConfig(config.view, \"ui\");\n\treturn (dispatcher) => {\n\t\tdispatcher.on(`addMarker:${config.model}`, insertUIElement(view), { priority: config.converterPriority || \"normal\" });\n\t\tdispatcher.on(`removeMarker:${config.model}`, removeUIElement(), { priority: config.converterPriority || \"normal\" });\n\t};\n}\n/**\n* Model marker to view data conversion helper.\n*\n* See {@link ~DowncastHelpers#markerToData `markerToData()` downcast helper} to learn more.\n*\n* @returns Conversion helper.\n*/\nfunction downcastMarkerToData(config) {\n\tconfig = cloneDeep(config);\n\tconst group = config.model;\n\tlet view = config.view;\n\tif (!view) view = (markerName) => ({\n\t\tgroup,\n\t\tname: markerName.substr(config.model.length + 1)\n\t});\n\treturn (dispatcher) => {\n\t\tdispatcher.on(`addMarker:${group}`, insertMarkerData(view), { priority: config.converterPriority || \"normal\" });\n\t\tdispatcher.on(`removeMarker:${group}`, removeMarkerData(view), { priority: config.converterPriority || \"normal\" });\n\t};\n}\n/**\n* Model marker to highlight conversion helper.\n*\n* See {@link ~DowncastHelpers#markerToElement `.markerToElement()` downcast helper} for examples.\n*\n* @param config Conversion configuration.\n* @param config.model The name of the model marker (or model marker group) to convert.\n* @param config.view A highlight descriptor that will be used for highlighting or a function that takes\n* the model marker data as a parameter and returns a highlight descriptor.\n* @param config.converterPriority Converter priority.\n* @returns Conversion helper.\n*/\nfunction downcastMarkerToHighlight(config) {\n\treturn (dispatcher) => {\n\t\tdispatcher.on(`addMarker:${config.model}`, highlightText(config.view), { priority: config.converterPriority || \"normal\" });\n\t\tdispatcher.on(`addMarker:${config.model}`, highlightElement(config.view), { priority: config.converterPriority || \"normal\" });\n\t\tdispatcher.on(`removeMarker:${config.model}`, removeHighlight(config.view), { priority: config.converterPriority || \"normal\" });\n\t};\n}\n/**\n* Takes `config.model`, and converts it to an object with normalized structure.\n*\n* @param model Model configuration or element name.\n*/\nfunction normalizeModelElementConfig(model) {\n\tif (typeof model == \"string\") model = { name: model };\n\treturn {\n\t\tname: model.name,\n\t\tattributes: model.attributes ? toArray(model.attributes) : [],\n\t\tchildren: !!model.children\n\t};\n}\n/**\n* Takes `config.view`, and if it is an {@link module:engine/view/elementdefinition~ViewElementDefinition}, converts it\n* to a function (because lower level converters accept only element creator functions).\n*\n* @param view View configuration.\n* @param viewElementType View element type to create.\n* @returns Element creator function to use in lower level converters.\n*/\nfunction normalizeToElementConfig(view, viewElementType) {\n\tif (typeof view == \"function\") return view;\n\treturn ((modelData, conversionApi) => createViewElementFromDefinition(view, conversionApi, viewElementType));\n}\n/**\n* Creates a view element instance from the provided {@link module:engine/view/elementdefinition~ViewElementDefinition} and class.\n*/\nfunction createViewElementFromDefinition(viewElementDefinition, conversionApi, viewElementType) {\n\tif (typeof viewElementDefinition == \"string\") viewElementDefinition = { name: viewElementDefinition };\n\tlet element;\n\tconst viewWriter = conversionApi.writer;\n\tconst attributes = Object.assign({}, viewElementDefinition.attributes);\n\tif (viewElementType == \"container\") element = viewWriter.createContainerElement(viewElementDefinition.name, attributes);\n\telse if (viewElementType == \"attribute\") {\n\t\tconst options = { priority: viewElementDefinition.priority || ViewAttributeElement.DEFAULT_PRIORITY };\n\t\telement = viewWriter.createAttributeElement(viewElementDefinition.name, attributes, options);\n\t} else element = viewWriter.createUIElement(viewElementDefinition.name, attributes);\n\tif (viewElementDefinition.styles) {\n\t\tconst keys = Object.keys(viewElementDefinition.styles);\n\t\tfor (const key of keys) viewWriter.setStyle(key, viewElementDefinition.styles[key], element);\n\t}\n\tif (viewElementDefinition.classes) {\n\t\tconst classes = viewElementDefinition.classes;\n\t\tif (typeof classes == \"string\") viewWriter.addClass(classes, element);\n\t\telse for (const className of classes) viewWriter.addClass(className, element);\n\t}\n\treturn element;\n}\nfunction getFromAttributeCreator(config) {\n\tif (config.model.values) return ((modelAttributeValue, conversionApi, data) => {\n\t\tconst view = config.view[modelAttributeValue];\n\t\tif (view) return view(modelAttributeValue, conversionApi, data);\n\t\treturn null;\n\t});\n\telse return config.view;\n}\n/**\n* Takes the configuration, adds default parameters if they do not exist and normalizes other parameters to be used in downcast converters\n* for generating a view attribute.\n*\n* @param view View configuration.\n*/\nfunction normalizeToAttributeConfig(view) {\n\tif (typeof view == \"string\") return (modelAttributeValue) => ({\n\t\tkey: view,\n\t\tvalue: modelAttributeValue\n\t});\n\telse if (typeof view == \"object\") if (view.value) return () => view;\n\telse return (modelAttributeValue) => ({\n\t\tkey: view.key,\n\t\tvalue: modelAttributeValue\n\t});\n\telse return view;\n}\n/**\n* Helper function for `highlight`. Prepares the actual descriptor object using value passed to the converter.\n*/\nfunction prepareDescriptor(highlightDescriptor, data, conversionApi) {\n\tconst descriptor = typeof highlightDescriptor == \"function\" ? highlightDescriptor(data, conversionApi) : { ...highlightDescriptor };\n\tif (!descriptor) return null;\n\tif (!descriptor.priority) descriptor.priority = 10;\n\tif (!descriptor.id) descriptor.id = data.markerName;\n\treturn descriptor;\n}\n/**\n* Creates a function that checks a single differ diff item whether it should trigger reconversion.\n*\n* @param model A normalized `config.model` converter configuration.\n* @param model.name The name of element.\n* @param model.attributes The list of attribute names that should trigger reconversion.\n* @param model.children Whether the child list change should trigger reconversion.\n*/\nfunction createChangeReducerCallback(model) {\n\treturn (node, change) => {\n\t\tif (!node.is(\"element\", model.name)) return false;\n\t\tif (change.type == \"attribute\") {\n\t\t\tif (model.attributes.includes(change.attributeKey)) return true;\n\t\t} else if (model.children) return true;\n\t\treturn false;\n\t};\n}\n/**\n* Creates a `reduceChanges` event handler for reconversion.\n*\n* @param model A normalized `config.model` converter configuration.\n* @param model.name The name of element.\n* @param model.attributes The list of attribute names that should trigger reconversion.\n* @param model.children Whether the child list change should trigger reconversion.\n*/\nfunction createChangeReducer(model) {\n\tconst shouldReplace = createChangeReducerCallback(model);\n\treturn (evt, data) => {\n\t\tconst reducedChanges = [];\n\t\tif (!data.reconvertedElements) data.reconvertedElements = /* @__PURE__ */ new Set();\n\t\tfor (const change of data.changes) {\n\t\t\tconst node = change.type == \"attribute\" ? change.range.start.nodeAfter : change.position.parent;\n\t\t\tif (!node || !shouldReplace(node, change) || change.type == \"reinsert\") {\n\t\t\t\treducedChanges.push(change);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (change.type == \"insert\" && change.action == \"rename\") data.refreshedItems.add(change.position.nodeAfter);\n\t\t\tif (!data.reconvertedElements.has(node)) {\n\t\t\t\tdata.reconvertedElements.add(node);\n\t\t\t\tconst position = ModelPosition._createBefore(node);\n\t\t\t\tlet changeIndex = reducedChanges.length;\n\t\t\t\tfor (let i = reducedChanges.length - 1; i >= 0; i--) {\n\t\t\t\t\tconst change = reducedChanges[i];\n\t\t\t\t\tconst positionRelation = (change.type == \"attribute\" ? change.range.start : change.position).compareWith(position);\n\t\t\t\t\tif (positionRelation == \"before\" || change.type == \"remove\" && positionRelation == \"same\") break;\n\t\t\t\t\tchangeIndex = i;\n\t\t\t\t}\n\t\t\t\treducedChanges.splice(changeIndex, 0, {\n\t\t\t\t\ttype: \"reinsert\",\n\t\t\t\t\tname: node.name,\n\t\t\t\t\tposition,\n\t\t\t\t\tlength: 1\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tdata.changes = reducedChanges;\n\t};\n}\n/**\n* Creates a function that checks if an element and its watched attributes can be consumed and consumes them.\n*\n* @param model A normalized `config.model` converter configuration.\n* @param model.name The name of element.\n* @param model.attributes The list of attribute names that should trigger reconversion.\n* @param model.children Whether the child list change should trigger reconversion.\n*/\nfunction createConsumer(model) {\n\treturn (node, consumable, options = {}) => {\n\t\tconst events = [\"insert\"];\n\t\tfor (const attributeName of model.attributes) if (node.hasAttribute(attributeName)) events.push(`attribute:${attributeName}`);\n\t\tif (!events.every((event) => consumable.test(node, event))) return false;\n\t\tif (!options.preflight) events.forEach((event) => consumable.consume(node, event));\n\t\treturn true;\n\t};\n}\n/**\n* Creates a function that creates view slots.\n*\n* @returns Function exposed by the writer as `createSlot()`.\n*/\nfunction createSlotFactory(element, slotsMap, conversionApi) {\n\treturn (writer, modeOrFilter) => {\n\t\tconst slot = writer.createContainerElement(\"$slot\");\n\t\tlet children;\n\t\tif (modeOrFilter === \"children\") children = Array.from(element.getChildren());\n\t\telse if (typeof modeOrFilter == \"function\") children = Array.from(element.getChildren()).filter((element) => modeOrFilter(element));\n\t\telse\n /**\n\t\t* Unknown slot mode was provided to `writer.createSlot()` in the downcast converter.\n\t\t*\n\t\t* @error conversion-slot-mode-unknown\n\t\t* @param {never} modeOrFilter The specified mode or filter.\n\t\t*/\n\t\tthrow new CKEditorError(\"conversion-slot-mode-unknown\", conversionApi.dispatcher, { modeOrFilter });\n\t\tslotsMap.set(slot, children);\n\t\treturn slot;\n\t};\n}\n/**\n* Checks if all children are covered by slots and there is no child that landed in multiple slots.\n*/\nfunction validateSlotsChildren(element, slotsMap, conversionApi) {\n\tconst childrenInSlots = Array.from(slotsMap.values()).flat();\n\tconst uniqueChildrenInSlots = new Set(childrenInSlots);\n\tif (uniqueChildrenInSlots.size != childrenInSlots.length)\n /**\n\t* Filters provided to `writer.createSlot()` overlap (at least two filters accept the same child element).\n\t*\n\t* @error conversion-slot-filter-overlap\n\t* @param {module:engine/model/element~ModelElement} element The element of which children would not be properly\n\t* allocated to multiple slots.\n\t*/\n\tthrow new CKEditorError(\"conversion-slot-filter-overlap\", conversionApi.dispatcher, { element });\n\tif (uniqueChildrenInSlots.size != element.childCount)\n /**\n\t* Filters provided to `writer.createSlot()` are incomplete and exclude at least one children element (one of\n\t* the children elements would not be assigned to any of the slots).\n\t*\n\t* @error conversion-slot-filter-incomplete\n\t* @param {module:engine/model/element~ModelElement} element The element of which children would not be properly\n\t* allocated to multiple slots.\n\t*/\n\tthrow new CKEditorError(\"conversion-slot-filter-incomplete\", conversionApi.dispatcher, { element });\n}\n/**\n* Fill slots with appropriate view elements.\n*/\nfunction fillSlots(viewElement, slotsMap, conversionApi, options) {\n\tconversionApi.mapper.on(\"modelToViewPosition\", toViewPositionMapping, { priority: \"highest\" });\n\tlet currentSlot = null;\n\tlet currentSlotNodes = null;\n\tfor ([currentSlot, currentSlotNodes] of slotsMap) {\n\t\treinsertOrConvertNodes(viewElement, currentSlotNodes, conversionApi, options);\n\t\tconversionApi.writer.setCustomProperty(\"$structureSlotParent\", true, currentSlot.parent);\n\t\tconversionApi.writer.move(conversionApi.writer.createRangeIn(currentSlot), conversionApi.writer.createPositionBefore(currentSlot));\n\t\tconversionApi.writer.remove(currentSlot);\n\t}\n\tconversionApi.mapper.off(\"modelToViewPosition\", toViewPositionMapping);\n\tfunction toViewPositionMapping(evt, data) {\n\t\tconst element = data.modelPosition.nodeAfter;\n\t\tconst index = currentSlotNodes.indexOf(element);\n\t\tif (index < 0) return;\n\t\tdata.viewPosition = data.mapper.findPositionIn(currentSlot, index);\n\t}\n}\n/**\n* Inserts view representation of `nodes` into the `viewElement` either by bringing back just removed view nodes\n* or by triggering conversion for them.\n*/\nfunction reinsertOrConvertNodes(viewElement, modelNodes, conversionApi, options) {\n\tfor (const modelChildNode of modelNodes) if (!reinsertNode(viewElement.root, modelChildNode, conversionApi, options)) conversionApi.convertItem(modelChildNode);\n}\n/**\n* Checks if the view for the given model element could be reused and reinserts it to the view.\n*\n* @returns `false` if view element can't be reused.\n*/\nfunction reinsertNode(viewRoot, modelNode, conversionApi, options) {\n\tconst { writer, mapper } = conversionApi;\n\tif (!options.reconversion) return false;\n\tconst viewChildNode = mapper.toViewElement(modelNode);\n\tif (!viewChildNode || viewChildNode.root == viewRoot) return false;\n\tif (!conversionApi.canReuseView(viewChildNode)) return false;\n\twriter.move(writer.createRangeOn(viewChildNode), mapper.toViewPosition(ModelPosition._createBefore(modelNode)));\n\treturn true;\n}\n/**\n* The default consumer for insert events.\n*\n* @param item Model item.\n* @param consumable The model consumable.\n* @param options.preflight Whether should consume or just check if can be consumed.\n*/\nfunction defaultConsumer(item, consumable, { preflight } = {}) {\n\tif (preflight) return consumable.test(item, \"insert\");\n\telse return consumable.consume(item, \"insert\");\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Fixes all empty roots.\n*\n* @internal\n* @param writer The model writer.\n* @returns `true` if any change has been applied, `false` otherwise.\n*/\nfunction autoParagraphEmptyRoots(writer) {\n\tconst { schema, document } = writer.model;\n\tfor (const root of document.getRoots()) if (root.isEmpty && !schema.checkChild(root, \"$text\")) {\n\t\tif (schema.checkChild(root, \"paragraph\")) {\n\t\t\twriter.insertElement(\"paragraph\", root);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n/**\n* Checks if the given node wrapped with a paragraph would be accepted by the schema in the given position.\n*\n* @internal\n* @param position The position at which to check.\n* @param nodeOrType The child node or child type to check.\n* @param schema A schema instance used for element validation.\n*/\nfunction isParagraphable(position, nodeOrType, schema) {\n\tconst context = schema.createContext(position);\n\tif (!schema.checkChild(context, \"paragraph\")) return false;\n\tif (!schema.checkChild(context.push(\"paragraph\"), nodeOrType)) return false;\n\treturn true;\n}\n/**\n* Inserts a new paragraph at the given position and returns a position inside that paragraph.\n*\n* @internal\n* @param position The position where a paragraph should be inserted.\n* @param writer The model writer.\n* @returns Position inside the created paragraph.\n*/\nfunction wrapInParagraph(position, writer) {\n\tconst paragraph = writer.createElement(\"paragraph\");\n\twriter.insert(paragraph, position);\n\treturn writer.createPositionAt(paragraph, 0);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Contains the {@link module:engine/view/view view} to {@link module:engine/model/model model} converters for\n* {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}.\n*\n* @module engine/conversion/upcasthelpers\n*/\n/**\n* Upcast conversion helper functions.\n*\n* Learn more about {@glink framework/deep-dive/conversion/upcast upcast helpers}.\n*\n* @extends module:engine/conversion/conversionhelpers~ConversionHelpers\n*/\nvar UpcastHelpers = class extends ConversionHelpers {\n\t/**\n\t* View element to model element conversion helper.\n\t*\n\t* This conversion results in creating a model element. For example,\n\t* view `<p>Foo</p>` becomes `<paragraph>Foo</paragraph>` in the model.\n\t*\n\t* Keep in mind that the element will be inserted only if it is allowed\n\t* by {@link module:engine/model/schema~ModelSchema schema} configuration.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'upcast' ).elementToElement( {\n\t* \tview: 'p',\n\t* \tmodel: 'paragraph'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToElement( {\n\t* \tview: 'p',\n\t* \tmodel: 'paragraph',\n\t* \tconverterPriority: 'high'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToElement( {\n\t* \tview: {\n\t* \t\tname: 'p',\n\t* \t\tclasses: 'fancy'\n\t* \t},\n\t* \tmodel: 'fancyParagraph'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToElement( {\n\t* \tview: {\n\t* \t\tname: 'p',\n\t* \t\tclasses: 'heading'\n\t* \t},\n\t* \tmodel: ( viewElement, conversionApi ) => {\n\t* \t\tconst modelWriter = conversionApi.writer;\n\t*\n\t* \t\treturn modelWriter.createElement( 'heading', { level: viewElement.getAttribute( 'data-level' ) } );\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.view Pattern matching all view elements which should be converted. If not set, the converter\n\t* will fire for every view element.\n\t* @param config.model Name of the model element, a model element instance or a function that takes a view element\n\t* and {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API}\n\t* and returns a model element. The model element will be inserted in the model.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\telementToElement(config) {\n\t\treturn this.add(upcastElementToElement(config));\n\t}\n\t/**\n\t* View element to model attribute conversion helper.\n\t*\n\t* This conversion results in setting an attribute on a model node. For example, view `<strong>Foo</strong>` becomes\n\t* `Foo` {@link module:engine/model/text~ModelText model text node} with `bold` attribute set to `true`.\n\t*\n\t* This helper is meant to set a model attribute on all the elements that are inside the converted element:\n\t*\n\t* ```\n\t* <strong>Foo</strong> --> <strong><p>Foo</p></strong> --> <paragraph><$text bold=\"true\">Foo</$text></paragraph>\n\t* ```\n\t*\n\t* Above is a sample of HTML code, that goes through autoparagraphing (first step) and then is converted (second step).\n\t* Even though `<strong>` is over `<p>` element, `bold=\"true\"` was added to the text. See\n\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#attributeToAttribute} for comparison.\n\t*\n\t* Keep in mind that the attribute will be set only if it is allowed by\n\t* {@link module:engine/model/schema~ModelSchema schema} configuration.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t* \tview: 'strong',\n\t* \tmodel: 'bold'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t* \tview: 'strong',\n\t* \tmodel: 'bold',\n\t* \tconverterPriority: 'high'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t* \tview: {\n\t* \t\tname: 'span',\n\t* \t\tclasses: 'bold'\n\t* \t},\n\t* \tmodel: 'bold'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t* \tview: {\n\t* \t\tname: 'span',\n\t* \t\tclasses: [ 'styled', 'styled-dark' ]\n\t* \t},\n\t* \tmodel: {\n\t* \t\tkey: 'styled',\n\t* \t\tvalue: 'dark'\n\t* \t}\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t* \tview: {\n\t* \t\tname: 'span',\n\t* \t\tstyles: {\n\t* \t\t\t'font-size': /[\\s\\S]+/\n\t* \t\t}\n\t* \t},\n\t* \tmodel: {\n\t* \t\tkey: 'fontSize',\n\t* \t\tvalue: ( viewElement, conversionApi ) => {\n\t* \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t* \t\t\tconst value = fontSize.substr( 0, fontSize.length - 2 );\n\t*\n\t* \t\t\tif ( value <= 10 ) {\n\t* \t\t\t\treturn 'small';\n\t* \t\t\t} else if ( value > 12 ) {\n\t* \t\t\t\treturn 'big';\n\t* \t\t\t}\n\t*\n\t* \t\t\treturn null;\n\t* \t\t}\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.view Pattern matching all view elements which should be converted.\n\t* @param config.model Model attribute key or an object with `key` and `value` properties, describing\n\t* the model attribute. `value` property may be set as a function that takes a view element and\n\t* {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the value.\n\t* If `String` is given, the model attribute value will be set to `true`.\n\t* @param config.converterPriority Converter priority. Defaults to `low`.\n\t*/\n\telementToAttribute(config) {\n\t\treturn this.add(upcastElementToAttribute(config));\n\t}\n\t/**\n\t* View attribute to model attribute conversion helper.\n\t*\n\t* This conversion results in setting an attribute on a model node. For example, view `<img src=\"foo.jpg\"></img>` becomes\n\t* `<imageBlock source=\"foo.jpg\"></imageBlock>` in the model.\n\t*\n\t* This helper is meant to convert view attributes from view elements which got converted to the model, so the view attribute\n\t* is set only on the corresponding model node:\n\t*\n\t* ```\n\t* <div class=\"dark\"><div>foo</div></div> --> <div dark=\"true\"><div>foo</div></div>\n\t* ```\n\t*\n\t* Above, `class=\"dark\"` attribute is added only to the `<div>` elements that has it. This is in contrast to\n\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToAttribute} which sets attributes for\n\t* all the children in the model:\n\t*\n\t* ```\n\t* <strong>Foo</strong> --> <strong><p>Foo</p></strong> --> <paragraph><$text bold=\"true\">Foo</$text></paragraph>\n\t* ```\n\t*\n\t* Above is a sample of HTML code, that goes through autoparagraphing (first step) and then is converted (second step).\n\t* Even though `<strong>` is over `<p>` element, `bold=\"true\"` was added to the text.\n\t*\n\t* Keep in mind that the attribute will be set only if it is allowed by\n\t* {@link module:engine/model/schema~ModelSchema schema} configuration.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t* \tview: 'src',\n\t* \tmodel: 'source'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t* \tview: { key: 'src' },\n\t* \tmodel: 'source'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t* \tview: { key: 'src' },\n\t* \tmodel: 'source',\n\t* \tconverterPriority: 'normal'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t* \tview: {\n\t* \t\tkey: 'data-style',\n\t* \t\tvalue: /[\\s\\S]+/\n\t* \t},\n\t* \tmodel: 'styled'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t* \tview: {\n\t* \t\tname: 'img',\n\t* \t\tkey: 'class',\n\t* \t\tvalue: 'styled-dark'\n\t* \t},\n\t* \tmodel: {\n\t* \t\tkey: 'styled',\n\t* \t\tvalue: 'dark'\n\t* \t}\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t* \tview: {\n\t* \t\tkey: 'class',\n\t* \t\tvalue: /styled-[\\S]+/\n\t* \t},\n\t* \tmodel: {\n\t* \t\tkey: 'styled'\n\t* \t\tvalue: ( viewElement, conversionApi ) => {\n\t* \t\t\tconst regexp = /styled-([\\S]+)/;\n\t* \t\t\tconst match = viewElement.getAttribute( 'class' ).match( regexp );\n\t*\n\t* \t\t\treturn match[ 1 ];\n\t* \t\t}\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* Converting styles works a bit differently as it requires `view.styles` to be an object and by default\n\t* a model attribute will be set to `true` by such a converter. You can set the model attribute to any value by providing the `value`\n\t* callback that returns the desired value.\n\t*\n\t* ```ts\n\t* // Default conversion of font-weight style will result in setting bold attribute to true.\n\t* editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t* \tview: {\n\t* \t\tstyles: {\n\t* \t\t\t'font-weight': 'bold'\n\t* \t\t}\n\t* \t},\n\t* \tmodel: 'bold'\n\t* } );\n\t*\n\t* // This converter will pass any style value to the `lineHeight` model attribute.\n\t* editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t* \tview: {\n\t* \t\tstyles: {\n\t* \t\t\t'line-height': /[\\s\\S]+/\n\t* \t\t}\n\t* \t},\n\t* \tmodel: {\n\t* \t\tkey: 'lineHeight',\n\t* \t\tvalue: ( viewElement, conversionApi ) => viewElement.getStyle( 'line-height' )\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.view Specifies which view attribute will be converted. If a `String` is passed,\n\t* attributes with given key will be converted. If an `Object` is passed, it must have a required `key` property,\n\t* specifying view attribute key, and may have an optional `value` property, specifying view attribute value and optional `name`\n\t* property specifying a view element name from/on which the attribute should be converted. `value` can be given as a `String`,\n\t* a `RegExp` or a function callback, that takes view attribute value as the only parameter and returns `Boolean`.\n\t* @param config.model Model attribute key or an object with `key` and `value` properties, describing\n\t* the model attribute. `value` property may be set as a function that takes a view element and\n\t* {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the value.\n\t* If `String` is given, the model attribute value will be same as view attribute value.\n\t* @param config.converterPriority Converter priority. Defaults to `low`.\n\t*/\n\tattributeToAttribute(config) {\n\t\treturn this.add(upcastAttributeToAttribute(config));\n\t}\n\t/**\n\t* View element to model marker conversion helper.\n\t*\n\t* This conversion results in creating a model marker. For example, if the marker was stored in a view as an element:\n\t* `<p>Fo<span data-marker=\"comment\" data-comment-id=\"7\"></span>o</p><p>B<span data-marker=\"comment\" data-comment-id=\"7\"></span>ar</p>`,\n\t* after the conversion is done, the marker will be available in\n\t* {@link module:engine/model/model~Model#markers model document markers}.\n\t*\n\t* **Note**: When this helper is used in the data upcast in combination with\n\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`} in the data downcast,\n\t* then invalid HTML code (e.g. a span between table cells) may be produced by the latter converter.\n\t*\n\t* In most of the cases, the {@link #dataToMarker} should be used instead.\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'upcast' ).elementToMarker( {\n\t* \tview: 'marker-search',\n\t* \tmodel: 'search'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToMarker( {\n\t* \tview: 'marker-search',\n\t* \tmodel: 'search',\n\t* \tconverterPriority: 'high'\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToMarker( {\n\t* \tview: 'marker-search',\n\t* \tmodel: ( viewElement, conversionApi ) => 'comment:' + viewElement.getAttribute( 'data-comment-id' )\n\t* } );\n\t*\n\t* editor.conversion.for( 'upcast' ).elementToMarker( {\n\t* \tview: {\n\t* \t\tname: 'span',\n\t* \t\tattributes: {\n\t* \t\t\t'data-marker': 'search'\n\t* \t\t}\n\t* \t},\n\t* \tmodel: 'search'\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.view Pattern matching all view elements which should be converted.\n\t* @param config.model Name of the model marker, or a function that takes a view element and returns\n\t* a model marker name.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\telementToMarker(config) {\n\t\treturn this.add(upcastElementToMarker(config));\n\t}\n\t/**\n\t* View-to-model marker conversion helper.\n\t*\n\t* Converts view data created by {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`}\n\t* back to a model marker.\n\t*\n\t* This converter looks for specific view elements and view attributes that mark marker boundaries. See\n\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`} to learn what view data\n\t* is expected by this converter.\n\t*\n\t* The `config.view` property is equal to the marker group name to convert.\n\t*\n\t* By default, this converter creates markers with the `group:name` name convention (to match the default `markerToData` conversion).\n\t*\n\t* The conversion configuration can take a function that will generate a marker name.\n\t* If such function is set as the `config.model` parameter, it is passed the `name` part from the view element or attribute and it is\n\t* expected to return a string with the marker name.\n\t*\n\t* Basic usage:\n\t*\n\t* ```ts\n\t* // Using the default conversion.\n\t* // In this case, all markers from the `comment` group will be converted.\n\t* // The conversion will look for `<comment-start>` and `<comment-end>` tags and\n\t* // `data-comment-start-before`, `data-comment-start-after`,\n\t* // `data-comment-end-before` and `data-comment-end-after` attributes.\n\t* editor.conversion.for( 'upcast' ).dataToMarker( {\n\t* \tview: 'comment'\n\t* } );\n\t* ```\n\t*\n\t* An example of a model that may be generated by this conversion:\n\t*\n\t* ```\n\t* // View:\n\t* <p>Foo<comment-start name=\"commentId:uid\"></comment-start>bar</p>\n\t* <figure data-comment-end-after=\"commentId:uid\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t*\n\t* // Model:\n\t* <paragraph>Foo[bar</paragraph>\n\t* <imageBlock src=\"abc.jpg\"></imageBlock>]\n\t* ```\n\t*\n\t* Where `[]` are boundaries of a marker that will receive the `comment:commentId:uid` name.\n\t*\n\t* Other examples of usage:\n\t*\n\t* ```ts\n\t* // Using a custom function which is the same as the default conversion:\n\t* editor.conversion.for( 'upcast' ).dataToMarker( {\n\t* \tview: 'comment',\n\t* \tmodel: ( name, conversionApi ) => 'comment:' + name,\n\t* } );\n\t*\n\t* // Using the converter priority:\n\t* editor.conversion.for( 'upcast' ).dataToMarker( {\n\t* \tview: 'comment',\n\t* \tmodel: ( name, conversionApi ) => 'comment:' + name,\n\t* \tconverterPriority: 'high'\n\t* } );\n\t* ```\n\t*\n\t* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t* to the conversion process.\n\t*\n\t* @param config Conversion configuration.\n\t* @param config.view The marker group name to convert.\n\t* @param config.model A function that takes the `name` part from the view element or attribute and\n\t* {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the marker name.\n\t* @param config.converterPriority Converter priority.\n\t*/\n\tdataToMarker(config) {\n\t\treturn this.add(upcastDataToMarker(config));\n\t}\n};\n/**\n* Function factory, creates a converter that converts\n* {@link module:engine/view/documentfragment~ViewDocumentFragment view document fragment}\n* or all children of {@link module:engine/view/element~ViewElement} into\n* {@link module:engine/model/documentfragment~ModelDocumentFragment model document fragment}.\n* This is the \"entry-point\" converter for upcast (view to model conversion). This converter starts the conversion of all children\n* of passed view document fragment. Those children {@link module:engine/view/node~ViewNode view nodes} are then\n* handled by other converters.\n*\n* This also a \"default\", last resort converter for all view elements that has not been converted by other converters.\n* When a view element is being converted to the model but it does not have converter specified, that view element\n* will be converted to {@link module:engine/model/documentfragment~ModelDocumentFragment model document fragment} and returned.\n*\n* @returns Universal converter for view {@link module:engine/view/documentfragment~ViewDocumentFragment fragments} and\n* {@link module:engine/view/element~ViewElement elements} that returns\n* {@link module:engine/model/documentfragment~ModelDocumentFragment model fragment} with children of converted view item.\n*\n* @internal\n*/\nfunction convertToModelFragment() {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!data.modelRange && conversionApi.consumable.consume(data.viewItem, { name: true })) {\n\t\t\tconst { modelRange, modelCursor } = conversionApi.convertChildren(data.viewItem, data.modelCursor);\n\t\t\tdata.modelRange = modelRange;\n\t\t\tdata.modelCursor = modelCursor;\n\t\t}\n\t};\n}\n/**\n* Function factory, creates a converter that converts\n* {@link module:engine/view/text~ViewText} to {@link module:engine/model/text~ModelText}.\n*\n* @returns {@link module:engine/view/text~ViewText View text} converter.\n* @internal\n*/\nfunction convertText() {\n\treturn (evt, data, { schema, consumable, writer }) => {\n\t\tlet position = data.modelCursor;\n\t\tif (!consumable.test(data.viewItem)) return;\n\t\tif (!schema.checkChild(position, \"$text\")) {\n\t\t\tif (!isParagraphable(position, \"$text\", schema)) return;\n\t\t\tif (data.viewItem.data.trim().length == 0) return;\n\t\t\tposition = wrapInParagraph(position, writer);\n\t\t}\n\t\tconsumable.consume(data.viewItem);\n\t\tconst text = writer.createText(data.viewItem.data);\n\t\twriter.insert(text, position);\n\t\tdata.modelRange = writer.createRange(position, position.getShiftedBy(text.offsetSize));\n\t\tdata.modelCursor = data.modelRange.end;\n\t};\n}\n/**\n* Function factory, creates a callback function which converts a {@link module:engine/view/selection~ViewSelection\n* view selection} taken from the {@link module:engine/view/document~ViewDocument#event:selectionChange} event\n* and sets in on the {@link module:engine/model/document~ModelDocument#selection model}.\n*\n* **Note**: because there is no view selection change dispatcher nor any other advanced view selection to model\n* conversion mechanism, the callback should be set directly on view document.\n*\n* ```ts\n* view.document.on( 'selectionChange', convertSelectionChange( modelDocument, mapper ) );\n* ```\n*\n* @param model Data model.\n* @param mapper Conversion mapper.\n* @returns {@link module:engine/view/document~ViewDocument#event:selectionChange} callback function.\n* @internal\n*/\nfunction convertSelectionChange(model, mapper) {\n\treturn (evt, data) => {\n\t\tconst viewSelection = data.newSelection;\n\t\tconst ranges = [];\n\t\tfor (const viewRange of viewSelection.getRanges()) ranges.push(mapper.toModelRange(viewRange));\n\t\tconst modelSelection = model.createSelection(ranges, { backward: viewSelection.isBackward });\n\t\tif (!modelSelection.isEqual(model.document.selection)) model.change((writer) => {\n\t\t\twriter.setSelection(modelSelection);\n\t\t});\n\t};\n}\n/**\n* View element to model element conversion helper.\n*\n* See {@link ~UpcastHelpers#elementToElement `.elementToElement()` upcast helper} for examples.\n*\n* @param config Conversion configuration.\n* @param config.view Pattern matching all view elements which should be converted. If not\n* set, the converter will fire for every view element.\n* @param config.model Name of the model element, a model element\n* instance or a function that takes a view element and returns a model element. The model element will be inserted in the model.\n* @param config.converterPriority Converter priority.\n* @returns Conversion helper.\n*/\nfunction upcastElementToElement(config) {\n\tconfig = cloneDeep(config);\n\tconst converter = prepareToElementConverter(config);\n\tconst elementName = getViewElementNameFromConfig(config.view);\n\tconst eventName = elementName ? `element:${elementName}` : \"element\";\n\treturn (dispatcher) => {\n\t\tdispatcher.on(eventName, converter, { priority: config.converterPriority || \"normal\" });\n\t};\n}\n/**\n* View element to model attribute conversion helper.\n*\n* See {@link ~UpcastHelpers#elementToAttribute `.elementToAttribute()` upcast helper} for examples.\n*\n* @param config Conversion configuration.\n* @param config.view Pattern matching all view elements which should be converted.\n* @param config.model Model attribute key or an object with `key` and `value` properties, describing\n* the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n* If `String` is given, the model attribute value will be set to `true`.\n* @param config.converterPriority Converter priority. Defaults to `low`.\n* @returns Conversion helper.\n*/\nfunction upcastElementToAttribute(config) {\n\tconfig = cloneDeep(config);\n\tnormalizeModelAttributeConfig(config);\n\tconst converter = prepareToAttributeConverter(config, false);\n\tconst elementName = getViewElementNameFromConfig(config.view);\n\tconst eventName = elementName ? `element:${elementName}` : \"element\";\n\treturn (dispatcher) => {\n\t\tdispatcher.on(eventName, converter, { priority: config.converterPriority || \"low\" });\n\t};\n}\n/**\n* View attribute to model attribute conversion helper.\n*\n* See {@link ~UpcastHelpers#attributeToAttribute `.attributeToAttribute()` upcast helper} for examples.\n*\n* @param config Conversion configuration.\n* @param config.view Specifies which view attribute will be converted. If a `String` is passed,\n* attributes with given key will be converted. If an `Object` is passed, it must have a required `key` property,\n* specifying view attribute key, and may have an optional `value` property, specifying view attribute value and optional `name`\n* property specifying a view element name from/on which the attribute should be converted. `value` can be given as a `String`,\n* a `RegExp` or a function callback, that takes view attribute value as the only parameter and returns `Boolean`.\n* @param config.model Model attribute key or an object with `key` and `value` properties, describing\n* the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n* If `String` is given, the model attribute value will be same as view attribute value.\n* @param config.converterPriority Converter priority. Defaults to `low`.\n* @returns Conversion helper.\n*/\nfunction upcastAttributeToAttribute(config) {\n\tconfig = cloneDeep(config);\n\tlet viewKey = null;\n\tif (typeof config.view == \"string\" || config.view.key) viewKey = normalizeViewAttributeKeyValueConfig(config);\n\tnormalizeModelAttributeConfig(config, viewKey);\n\tconst converter = prepareToAttributeConverter(config, true);\n\treturn (dispatcher) => {\n\t\tdispatcher.on(\"element\", converter, { priority: config.converterPriority || \"low\" });\n\t};\n}\n/**\n* View element to model marker conversion helper.\n*\n* See {@link ~UpcastHelpers#elementToMarker `.elementToMarker()` upcast helper} for examples.\n*\n* @param config Conversion configuration.\n* @param config.view Pattern matching all view elements which should be converted.\n* @param config.model Name of the model marker, or a function that takes a view element and returns\n* a model marker name.\n* @param config.converterPriority Converter priority.\n* @returns Conversion helper.\n*/\nfunction upcastElementToMarker(config) {\n\tconst model = normalizeElementToMarkerModelConfig(config.model);\n\treturn upcastElementToElement({\n\t\t...config,\n\t\tmodel\n\t});\n}\n/**\n* View data to model marker conversion helper.\n*\n* See {@link ~UpcastHelpers#dataToMarker} to learn more.\n*\n* @returns Conversion helper.\n*/\nfunction upcastDataToMarker(config) {\n\tconfig = cloneDeep(config);\n\tif (!config.model) config.model = (name) => {\n\t\treturn name ? config.view + \":\" + name : config.view;\n\t};\n\tconst normalizedConfig = {\n\t\tview: config.view,\n\t\tmodel: config.model\n\t};\n\tconst converterStart = prepareToElementConverter(normalizeDataToMarkerConfig(normalizedConfig, \"start\"));\n\tconst converterEnd = prepareToElementConverter(normalizeDataToMarkerConfig(normalizedConfig, \"end\"));\n\treturn (dispatcher) => {\n\t\tdispatcher.on(`element:${config.view}-start`, converterStart, { priority: config.converterPriority || \"normal\" });\n\t\tdispatcher.on(`element:${config.view}-end`, converterEnd, { priority: config.converterPriority || \"normal\" });\n\t\tconst basePriority = priorities.low;\n\t\tconst maxPriority = priorities.highest;\n\t\tconst priorityFactor = priorities.get(config.converterPriority) / maxPriority;\n\t\tdispatcher.on(\"element\", upcastAttributeToMarker(normalizedConfig), { priority: basePriority + priorityFactor });\n\t};\n}\n/**\n* Function factory, returns a callback function which converts view attributes to a model marker.\n*\n* The converter looks for elements with `data-group-start-before`, `data-group-start-after`, `data-group-end-before`\n* and `data-group-end-after` attributes and inserts `$marker` model elements before/after those elements.\n* `group` part is specified in `config.view`.\n*\n* @returns Marker converter.\n*/\nfunction upcastAttributeToMarker(config) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst attrName = `data-${config.view}`;\n\t\tif (!conversionApi.consumable.test(data.viewItem, { attributes: attrName + \"-end-after\" }) && !conversionApi.consumable.test(data.viewItem, { attributes: attrName + \"-start-after\" }) && !conversionApi.consumable.test(data.viewItem, { attributes: attrName + \"-end-before\" }) && !conversionApi.consumable.test(data.viewItem, { attributes: attrName + \"-start-before\" })) return;\n\t\tif (!data.modelRange) Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n\t\tif (conversionApi.consumable.consume(data.viewItem, { attributes: attrName + \"-end-after\" })) addMarkerElements(data.modelRange.end, data.viewItem.getAttribute(attrName + \"-end-after\").split(\",\"));\n\t\tif (conversionApi.consumable.consume(data.viewItem, { attributes: attrName + \"-start-after\" })) addMarkerElements(data.modelRange.end, data.viewItem.getAttribute(attrName + \"-start-after\").split(\",\"));\n\t\tif (conversionApi.consumable.consume(data.viewItem, { attributes: attrName + \"-end-before\" })) addMarkerElements(data.modelRange.start, data.viewItem.getAttribute(attrName + \"-end-before\").split(\",\"));\n\t\tif (conversionApi.consumable.consume(data.viewItem, { attributes: attrName + \"-start-before\" })) addMarkerElements(data.modelRange.start, data.viewItem.getAttribute(attrName + \"-start-before\").split(\",\"));\n\t\tfunction addMarkerElements(position, markerViewNames) {\n\t\t\tfor (const markerViewName of markerViewNames) {\n\t\t\t\tconst markerName = config.model(markerViewName, conversionApi);\n\t\t\t\tconst element = conversionApi.writer.createElement(\"$marker\", { \"data-name\": markerName });\n\t\t\t\tconversionApi.writer.insert(element, position);\n\t\t\t\tif (data.modelCursor.isEqual(position)) data.modelCursor = data.modelCursor.getShiftedBy(1);\n\t\t\t\telse data.modelCursor = data.modelCursor._getTransformedByInsertion(position, 1);\n\t\t\t\tdata.modelRange = data.modelRange._getTransformedByInsertion(position, 1)[0];\n\t\t\t}\n\t\t}\n\t};\n}\n/**\n* Helper function for from-view-element conversion. Checks if `config.view` directly specifies converted view element's name\n* and if so, returns it.\n*\n* @param config Conversion view config.\n* @returns View element name or `null` if name is not directly set.\n*/\nfunction getViewElementNameFromConfig(viewConfig) {\n\tif (typeof viewConfig == \"string\") return viewConfig;\n\tif (typeof viewConfig == \"object\" && typeof viewConfig.name == \"string\") return viewConfig.name;\n\treturn null;\n}\n/**\n* Helper for to-model-element conversion. Takes a config object and returns a proper converter function.\n*\n* @param config Conversion configuration.\n* @returns View to model converter.\n*/\nfunction prepareToElementConverter(config) {\n\tconst matcher = new Matcher(config.view);\n\treturn (evt, data, conversionApi) => {\n\t\tconst matcherResult = matcher.match(data.viewItem);\n\t\tif (!matcherResult) return;\n\t\tconst match = matcherResult.match;\n\t\tmatch.name = true;\n\t\tif (!conversionApi.consumable.test(data.viewItem, match)) return;\n\t\tconst modelElement = getModelElement(config.model, data.viewItem, conversionApi);\n\t\tif (!modelElement) return;\n\t\tif (!conversionApi.safeInsert(modelElement, data.modelCursor)) return;\n\t\tconversionApi.consumable.consume(data.viewItem, match);\n\t\tconversionApi.convertChildren(data.viewItem, modelElement);\n\t\tconversionApi.updateConversionResult(modelElement, data);\n\t};\n}\n/**\n* Helper function for upcasting-to-element converter. Takes the model configuration, the converted view element\n* and a writer instance and returns a model element instance to be inserted in the model.\n*\n* @param model Model conversion configuration.\n* @param input The converted view node.\n* @param conversionApi The upcast conversion API.\n*/\nfunction getModelElement(model, input, conversionApi) {\n\tif (model instanceof Function) return model(input, conversionApi);\n\telse return conversionApi.writer.createElement(model);\n}\n/**\n* Helper function view-attribute-to-model-attribute helper. Normalizes `config.view` which was set as `String` or\n* as an `Object` with `key`, `value` and `name` properties. Normalized `config.view` has is compatible with\n* {@link module:engine/view/matcher~MatcherPattern}.\n*\n* @param config Conversion config.\n* @returns Key of the converted view attribute.\n*/\nfunction normalizeViewAttributeKeyValueConfig(config) {\n\tif (typeof config.view == \"string\") config.view = { key: config.view };\n\tconst key = config.view.key;\n\tconst value = typeof config.view.value == \"undefined\" ? /[\\s\\S]*/ : config.view.value;\n\tlet normalized;\n\tif (key == \"class\" || key == \"style\") normalized = { [key == \"class\" ? \"classes\" : \"styles\"]: value };\n\telse normalized = { attributes: { [key]: value } };\n\tif (config.view.name) normalized.name = config.view.name;\n\tconfig.view = normalized;\n\treturn key;\n}\n/**\n* Helper function that normalizes `config.model` in from-model-attribute conversion. `config.model` can be set\n* as a `String`, an `Object` with only `key` property or an `Object` with `key` and `value` properties. Normalized\n* `config.model` is an `Object` with `key` and `value` properties.\n*\n* @param config Conversion config.\n* @param viewAttributeKeyToCopy Key of the converted view attribute. If it is set, model attribute value\n* will be equal to view attribute value.\n*/\nfunction normalizeModelAttributeConfig(config, viewAttributeKeyToCopy = null) {\n\tconst defaultModelValue = viewAttributeKeyToCopy === null ? true : (viewElement) => viewElement.getAttribute(viewAttributeKeyToCopy);\n\tconfig.model = {\n\t\tkey: typeof config.model != \"object\" ? config.model : config.model.key,\n\t\tvalue: typeof config.model != \"object\" || typeof config.model.value == \"undefined\" ? defaultModelValue : config.model.value\n\t};\n}\n/**\n* Helper for to-model-attribute conversion. Takes the model attribute name and conversion configuration and returns\n* a proper converter function.\n*\n* @param config Conversion configuration. It is possible to provide multiple configurations in an array.\n* @param shallow If set to `true` the attribute will be set only on top-level nodes. Otherwise, it will be set\n* on all elements in the range.\n*/\nfunction prepareToAttributeConverter(config, shallow) {\n\tconst matcher = new Matcher(config.view);\n\treturn (evt, data, conversionApi) => {\n\t\tif (!data.modelRange && shallow) return;\n\t\tconst match = matcher.match(data.viewItem);\n\t\tif (!match) return;\n\t\tif (onlyViewNameIsDefined(config.view, data.viewItem)) match.match.name = true;\n\t\telse delete match.match.name;\n\t\tif (!conversionApi.consumable.test(data.viewItem, match.match)) return;\n\t\tconst modelKey = config.model.key;\n\t\tconst modelValue = typeof config.model.value == \"function\" ? config.model.value(data.viewItem, conversionApi, data) : config.model.value;\n\t\tif (modelValue === null || modelValue === void 0) return;\n\t\tif (!data.modelRange) Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n\t\tif (setAttributeOn(data.modelRange, {\n\t\t\tkey: modelKey,\n\t\t\tvalue: modelValue\n\t\t}, shallow, conversionApi)) {\n\t\t\tif (conversionApi.consumable.test(data.viewItem, { name: true })) match.match.name = true;\n\t\t\tconversionApi.consumable.consume(data.viewItem, match.match);\n\t\t}\n\t};\n}\n/**\n* Helper function that checks if element name should be consumed in attribute converters.\n*\n* @param viewConfig Conversion view config.\n*/\nfunction onlyViewNameIsDefined(viewConfig, viewItem) {\n\tconst configToTest = typeof viewConfig == \"function\" ? viewConfig(viewItem) : viewConfig;\n\tif (typeof configToTest == \"object\" && !getViewElementNameFromConfig(configToTest)) return false;\n\treturn !configToTest.classes && !configToTest.attributes && !configToTest.styles;\n}\n/**\n* Helper function for to-model-attribute converter. Sets model attribute on given range.\n* Checks {@link module:engine/model/schema~ModelSchema} to ensure proper model structure.\n*\n* If any node on the given range has already defined an attribute with the same name, its value will not be updated.\n*\n* @param modelRange Model range on which attribute should be set.\n* @param modelAttribute Model attribute to set.\n* @param conversionApi Conversion API.\n* @param shallow If set to `true` the attribute will be set only on top-level nodes. Otherwise, it will be set\n* on all elements in the range.\n* @returns `true` if attribute was set on at least one node from given `modelRange`.\n*/\nfunction setAttributeOn(modelRange, modelAttribute, shallow, conversionApi) {\n\tlet result = false;\n\tfor (const node of Array.from(modelRange.getItems({ shallow }))) {\n\t\tif (!conversionApi.schema.checkAttribute(node, modelAttribute.key)) continue;\n\t\tresult = true;\n\t\tif (node.hasAttribute(modelAttribute.key)) continue;\n\t\tconversionApi.writer.setAttribute(modelAttribute.key, modelAttribute.value, node);\n\t}\n\treturn result;\n}\n/**\n* Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastElementToMarker()`\n* function and converts it to a format that is supported by `upcastElementToElement()` function.\n*/\nfunction normalizeElementToMarkerModelConfig(model) {\n\treturn (viewElement, conversionApi) => {\n\t\tconst markerName = typeof model == \"string\" ? model : model(viewElement, conversionApi);\n\t\treturn conversionApi.writer.createElement(\"$marker\", { \"data-name\": markerName });\n\t};\n}\n/**\n* Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastDataToMarker()`\n* function and converts it to a format that is supported by `upcastElementToElement()` function.\n*/\nfunction normalizeDataToMarkerConfig(config, type) {\n\tconst elementCreatorFunction = (viewElement, conversionApi) => {\n\t\tconst viewName = viewElement.getAttribute(\"name\");\n\t\tconst markerName = config.model(viewName, conversionApi);\n\t\treturn conversionApi.writer.createElement(\"$marker\", { \"data-name\": markerName });\n\t};\n\treturn {\n\t\tview: `${config.view}-${type}`,\n\t\tmodel: elementCreatorFunction\n\t};\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/controller/editingcontroller\n*/\nconst EditingControllerBase = /* #__PURE__ */ ObservableMixin();\n/**\n* A controller for the editing pipeline. The editing pipeline controls the {@link ~EditingController#model model} rendering,\n* including selection handling. It also creates the {@link ~EditingController#view view} which builds a\n* browser-independent virtualization over the DOM elements. The editing controller also attaches default converters.\n*/\nvar EditingController = class extends EditingControllerBase {\n\t/**\n\t* Editor model.\n\t*/\n\tmodel;\n\t/**\n\t* Editing view controller.\n\t*/\n\tview;\n\t/**\n\t* A mapper that describes the model-view binding.\n\t*/\n\tmapper;\n\t/**\n\t* Downcast dispatcher that converts changes from the model to the {@link #view editing view}.\n\t*/\n\tdowncastDispatcher;\n\t/**\n\t* Creates an editing controller instance.\n\t*\n\t* @param model Editing model.\n\t* @param stylesProcessor The styles processor instance.\n\t*/\n\tconstructor(model, stylesProcessor) {\n\t\tsuper();\n\t\tthis.model = model;\n\t\tthis.view = new EditingView(stylesProcessor);\n\t\tthis.mapper = new Mapper();\n\t\tthis.downcastDispatcher = new DowncastDispatcher({\n\t\t\tmapper: this.mapper,\n\t\t\tschema: model.schema\n\t\t});\n\t\tconst doc = this.model.document;\n\t\tconst selection = doc.selection;\n\t\tconst markers = this.model.markers;\n\t\tthis.listenTo(this.model, \"_beforeChanges\", () => {\n\t\t\tthis.view._disableRendering(true);\n\t\t}, { priority: \"highest\" });\n\t\tthis.listenTo(this.model, \"_afterChanges\", () => {\n\t\t\tthis.view._disableRendering(false);\n\t\t}, { priority: \"lowest\" });\n\t\tthis.listenTo(doc, \"change\", () => {\n\t\t\tthis.view.change((writer) => {\n\t\t\t\tthis.downcastDispatcher.convertChanges(doc.differ, markers, writer);\n\t\t\t\tthis.downcastDispatcher.convertSelection(selection, markers, writer);\n\t\t\t});\n\t\t}, { priority: \"low\" });\n\t\tthis.listenTo(this.view.document, \"selectionChange\", convertSelectionChange(this.model, this.mapper));\n\t\tthis.downcastDispatcher.on(\"insert:$text\", insertText(), { priority: \"lowest\" });\n\t\tthis.downcastDispatcher.on(\"insert\", insertAttributesAndChildren(), { priority: \"lowest\" });\n\t\tthis.downcastDispatcher.on(\"remove\", remove(), { priority: \"low\" });\n\t\tthis.downcastDispatcher.on(\"cleanSelection\", cleanSelection());\n\t\tthis.downcastDispatcher.on(\"selection\", convertRangeSelection(), { priority: \"low\" });\n\t\tthis.downcastDispatcher.on(\"selection\", convertCollapsedSelection(), { priority: \"low\" });\n\t\tthis.view.document.roots.bindTo(this.model.document.roots).using((root) => {\n\t\t\tif (root.rootName == \"$graveyard\") return null;\n\t\t\tconst viewRoot = new ViewRootEditableElement(this.view.document, root.name);\n\t\t\tviewRoot.rootName = root.rootName;\n\t\t\tthis.mapper.bindElements(root, viewRoot);\n\t\t\treturn viewRoot;\n\t\t});\n\t}\n\t/**\n\t* Removes all event listeners attached to the `EditingController`. Destroys all objects created\n\t* by `EditingController` that need to be destroyed.\n\t*/\n\tdestroy() {\n\t\tthis.view.destroy();\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Calling this method will refresh the marker by triggering the downcast conversion for it.\n\t*\n\t* Reconverting the marker is useful when you want to change its {@link module:engine/view/element~ViewElement view element}\n\t* without changing any marker data. For instance:\n\t*\n\t* ```ts\n\t* let isCommentActive = false;\n\t*\n\t* model.conversion.markerToHighlight( {\n\t* \tmodel: 'comment',\n\t* \tview: data => {\n\t* \t\tconst classes = [ 'comment-marker' ];\n\t*\n\t* \t\tif ( isCommentActive ) {\n\t* \t\t\tclasses.push( 'comment-marker--active' );\n\t* \t\t}\n\t*\n\t* \t\treturn { classes };\n\t* \t}\n\t* } );\n\t*\n\t* // ...\n\t*\n\t* // Change the property that indicates if marker is displayed as active or not.\n\t* isCommentActive = true;\n\t*\n\t* // Reconverting will downcast and synchronize the marker with the new isCommentActive state value.\n\t* editor.editing.reconvertMarker( 'comment' );\n\t* ```\n\t*\n\t* **Note**: If you want to reconvert a model item, use {@link #reconvertItem} instead.\n\t*\n\t* @param markerOrName Name of a marker to update, or a marker instance.\n\t*/\n\treconvertMarker(markerOrName) {\n\t\tconst markerName = typeof markerOrName == \"string\" ? markerOrName : markerOrName.name;\n\t\tconst currentMarker = this.model.markers.get(markerName);\n\t\tif (!currentMarker)\n /**\n\t\t* The marker with the provided name does not exist and cannot be reconverted.\n\t\t*\n\t\t* @error editingcontroller-reconvertmarker-marker-not-exist\n\t\t* @param {string} markerName The name of the reconverted marker.\n\t\t*/\n\t\tthrow new CKEditorError(\"editingcontroller-reconvertmarker-marker-not-exist\", this, { markerName });\n\t\tthis.model.change(() => {\n\t\t\tthis.model.markers._refresh(currentMarker);\n\t\t});\n\t}\n\t/**\n\t* Calling this method will downcast a model item on demand (by requesting a refresh in the {@link module:engine/model/differ~Differ}).\n\t*\n\t* You can use it if you want the view representation of a specific item updated as a response to external modifications. For instance,\n\t* when the view structure depends not only on the associated model data but also on some external state.\n\t*\n\t* **Note**: If you want to reconvert a model marker, use {@link #reconvertMarker} instead.\n\t*\n\t* @param item Item to refresh.\n\t*/\n\treconvertItem(item) {\n\t\tthis.model.change(() => {\n\t\t\tthis.model.document.differ._refreshItem(item);\n\t\t});\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/schema\n*/\nconst ModelSchemaBase = /* #__PURE__ */ ObservableMixin();\n/**\n* The model's schema. It defines the allowed and disallowed structures of nodes as well as nodes' attributes.\n* The schema is usually defined by the features and based on them, the editing framework and features\n* make decisions on how to change and process the model.\n*\n* The instance of schema is available in {@link module:engine/model/model~Model#schema `editor.model.schema`}.\n*\n* Read more about the schema in:\n*\n* * The {@glink framework/architecture/editing-engine#schema schema section} of the\n* {@glink framework/architecture/editing-engine Introduction to the Editing engine architecture} guide.\n* * The {@glink framework/deep-dive/schema Schema deep-dive} guide.\n*/\nvar ModelSchema = class extends ModelSchemaBase {\n\t_sourceDefinitions = {};\n\t/**\n\t* A dictionary containing attribute properties.\n\t*/\n\t_attributeProperties = Object.create(null);\n\t/**\n\t* Stores additional callbacks registered for schema items, which are evaluated when {@link ~ModelSchema#checkChild} is called.\n\t*\n\t* Keys are schema item names for which the callbacks are registered. Values are arrays with the callbacks.\n\t*\n\t* Some checks are added under {@link ~ModelSchema#_genericCheckSymbol} key, these are\n\t* evaluated for every {@link ~ModelSchema#checkChild} call.\n\t*/\n\t_customChildChecks = /* @__PURE__ */ new Map();\n\t/**\n\t* Stores additional callbacks registered for attribute names, which are evaluated when {@link ~ModelSchema#checkAttribute} is called.\n\t*\n\t* Keys are schema attribute names for which the callbacks are registered. Values are arrays with the callbacks.\n\t*\n\t* Some checks are added under {@link ~ModelSchema#_genericCheckSymbol} key, these are evaluated for every\n\t* {@link ~ModelSchema#checkAttribute} call.\n\t*/\n\t_customAttributeChecks = /* @__PURE__ */ new Map();\n\t_genericCheckSymbol = Symbol(\"$generic\");\n\t_compiledDefinitions;\n\t/**\n\t* Creates a schema instance.\n\t*/\n\tconstructor() {\n\t\tsuper();\n\t\tthis.decorate(\"checkChild\");\n\t\tthis.decorate(\"checkAttribute\");\n\t\tthis.on(\"checkAttribute\", (evt, args) => {\n\t\t\targs[0] = new ModelSchemaContext(args[0]);\n\t\t}, { priority: \"highest\" });\n\t\tthis.on(\"checkChild\", (evt, args) => {\n\t\t\targs[0] = new ModelSchemaContext(args[0]);\n\t\t\targs[1] = this.getDefinition(args[1]);\n\t\t}, { priority: \"highest\" });\n\t}\n\t/**\n\t* Registers a schema item. Can only be called once for every item name.\n\t*\n\t* ```ts\n\t* schema.register( 'paragraph', {\n\t* \tinheritAllFrom: '$block'\n\t* } );\n\t* ```\n\t*/\n\tregister(itemName, definition) {\n\t\tif (this._sourceDefinitions[itemName])\n /**\n\t\t* A single item cannot be registered twice in the schema.\n\t\t*\n\t\t* This situation may happen when:\n\t\t*\n\t\t* * Two or more plugins called {@link module:engine/model/schema~ModelSchema#register `register()`} with the same name.\n\t\t* This will usually mean that there is a collision between plugins which try to use the same element in the model.\n\t\t* Unfortunately, the only way to solve this is by modifying one of these plugins to use a unique model element name.\n\t\t* * A single plugin was loaded twice. This happens when it is installed by npm/yarn in two versions\n\t\t* and usually means one or more of the following issues:\n\t\t* * a version mismatch (two of your dependencies require two different versions of this plugin),\n\t\t* * incorrect imports (this plugin is somehow imported twice in a way which confuses webpack),\n\t\t* * mess in `node_modules/` (`rm -rf node_modules/` may help).\n\t\t*\n\t\t* **Note:** Check the logged `itemName` to better understand which plugin was duplicated/conflicting.\n\t\t*\n\t\t* @param itemName The name of the model element that is being registered twice.\n\t\t* @error schema-cannot-register-item-twice\n\t\t*/\n\t\tthrow new CKEditorError(\"schema-cannot-register-item-twice\", this, { itemName });\n\t\tthis._sourceDefinitions[itemName] = [Object.assign({}, definition)];\n\t\tthis._clearCache();\n\t}\n\t/**\n\t* Extends a {@link #register registered} item's definition.\n\t*\n\t* Extending properties such as `allowIn` will add more items to the existing properties,\n\t* while redefining properties such as `isBlock` will override the previously defined ones.\n\t*\n\t* ```ts\n\t* schema.register( 'foo', {\n\t* \tallowIn: '$root',\n\t* \tisBlock: true;\n\t* } );\n\t* schema.extend( 'foo', {\n\t* \tallowIn: 'blockQuote',\n\t* \tisBlock: false\n\t* } );\n\t*\n\t* schema.getDefinition( 'foo' );\n\t* //\t{\n\t* //\t\tallowIn: [ '$root', 'blockQuote' ],\n\t* // \t\tisBlock: false\n\t* //\t}\n\t* ```\n\t*/\n\textend(itemName, definition) {\n\t\tif (!this._sourceDefinitions[itemName])\n /**\n\t\t* Cannot extend an item which was not registered yet.\n\t\t*\n\t\t* This error happens when a plugin tries to extend the schema definition of an item which was not\n\t\t* {@link module:engine/model/schema~ModelSchema#register registered} yet.\n\t\t*\n\t\t* @param itemName The name of the model element which is being extended.\n\t\t* @error schema-cannot-extend-missing-item\n\t\t*/\n\t\tthrow new CKEditorError(\"schema-cannot-extend-missing-item\", this, { itemName });\n\t\tthis._sourceDefinitions[itemName].push(Object.assign({}, definition));\n\t\tthis._clearCache();\n\t}\n\t/**\n\t* Returns data of all registered items.\n\t*\n\t* This method should normally be used for reflection purposes (e.g. defining a clone of a certain element,\n\t* checking a list of all block elements, etc).\n\t* Use specific methods (such as {@link #checkChild `checkChild()`} or {@link #isLimit `isLimit()`})\n\t* in other cases.\n\t*/\n\tgetDefinitions() {\n\t\tif (!this._compiledDefinitions) this._compile();\n\t\treturn this._compiledDefinitions;\n\t}\n\t/**\n\t* Returns a definition of the given item or `undefined` if an item is not registered.\n\t*\n\t* This method should normally be used for reflection purposes (e.g. defining a clone of a certain element,\n\t* checking a list of all block elements, etc).\n\t* Use specific methods (such as {@link #checkChild `checkChild()`} or {@link #isLimit `isLimit()`})\n\t* in other cases.\n\t*/\n\tgetDefinition(item) {\n\t\tlet itemName;\n\t\tif (typeof item == \"string\") itemName = item;\n\t\telse if (\"is\" in item && (item.is(\"$text\") || item.is(\"$textProxy\"))) itemName = \"$text\";\n\t\telse itemName = item.name;\n\t\treturn this.getDefinitions()[itemName];\n\t}\n\t/**\n\t* Returns `true` if the given item is registered in the schema.\n\t*\n\t* ```ts\n\t* schema.isRegistered( 'paragraph' ); // -> true\n\t* schema.isRegistered( editor.model.document.getRoot() ); // -> true\n\t* schema.isRegistered( 'foo' ); // -> false\n\t* ```\n\t*/\n\tisRegistered(item) {\n\t\treturn !!this.getDefinition(item);\n\t}\n\t/**\n\t* Returns `true` if the given item is defined to be\n\t* a block by the {@link module:engine/model/schema~ModelSchemaItemDefinition}'s `isBlock` property.\n\t*\n\t* ```ts\n\t* schema.isBlock( 'paragraph' ); // -> true\n\t* schema.isBlock( '$root' ); // -> false\n\t*\n\t* const paragraphElement = writer.createElement( 'paragraph' );\n\t* schema.isBlock( paragraphElement ); // -> true\n\t* ```\n\t*\n\t* See the {@glink framework/deep-dive/schema#block-elements Block elements} section of\n\t* the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*/\n\tisBlock(item) {\n\t\tconst def = this.getDefinition(item);\n\t\treturn !!(def && def.isBlock);\n\t}\n\t/**\n\t* Returns `true` if the given item should be treated as a limit element.\n\t*\n\t* It considers an item to be a limit element if its\n\t* {@link module:engine/model/schema~ModelSchemaItemDefinition}'s\n\t* {@link module:engine/model/schema~ModelSchemaItemDefinition#isLimit `isLimit`} or\n\t* {@link module:engine/model/schema~ModelSchemaItemDefinition#isObject `isObject`} property\n\t* was set to `true`.\n\t*\n\t* ```ts\n\t* schema.isLimit( 'paragraph' ); // -> false\n\t* schema.isLimit( '$root' ); // -> true\n\t* schema.isLimit( editor.model.document.getRoot() ); // -> true\n\t* schema.isLimit( 'imageBlock' ); // -> true\n\t* ```\n\t*\n\t* See the {@glink framework/deep-dive/schema#limit-elements Limit elements} section of\n\t* the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*/\n\tisLimit(item) {\n\t\tconst def = this.getDefinition(item);\n\t\tif (!def) return false;\n\t\treturn !!(def.isLimit || def.isObject);\n\t}\n\t/**\n\t* Returns `true` if the given item should be treated as an object element.\n\t*\n\t* It considers an item to be an object element if its\n\t* {@link module:engine/model/schema~ModelSchemaItemDefinition}'s\n\t* {@link module:engine/model/schema~ModelSchemaItemDefinition#isObject `isObject`} property\n\t* was set to `true`.\n\t*\n\t* ```ts\n\t* schema.isObject( 'paragraph' ); // -> false\n\t* schema.isObject( 'imageBlock' ); // -> true\n\t*\n\t* const imageElement = writer.createElement( 'imageBlock' );\n\t* schema.isObject( imageElement ); // -> true\n\t* ```\n\t*\n\t* See the {@glink framework/deep-dive/schema#object-elements Object elements} section of\n\t* the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*/\n\tisObject(item) {\n\t\tconst def = this.getDefinition(item);\n\t\tif (!def) return false;\n\t\treturn !!(def.isObject || def.isLimit && def.isSelectable && def.isContent);\n\t}\n\t/**\n\t* Returns `true` if the given item is defined to be\n\t* an inline element by the {@link module:engine/model/schema~ModelSchemaItemDefinition}'s `isInline` property.\n\t*\n\t* ```ts\n\t* schema.isInline( 'paragraph' ); // -> false\n\t* schema.isInline( 'softBreak' ); // -> true\n\t*\n\t* const text = writer.createText( 'foo' );\n\t* schema.isInline( text ); // -> true\n\t* ```\n\t*\n\t* See the {@glink framework/deep-dive/schema#inline-elements Inline elements} section of\n\t* the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*/\n\tisInline(item) {\n\t\tconst def = this.getDefinition(item);\n\t\treturn !!(def && def.isInline);\n\t}\n\t/**\n\t* Returns `true` if the given item is defined to be\n\t* a selectable element by the {@link module:engine/model/schema~ModelSchemaItemDefinition}'s `isSelectable` property.\n\t*\n\t* ```ts\n\t* schema.isSelectable( 'paragraph' ); // -> false\n\t* schema.isSelectable( 'heading1' ); // -> false\n\t* schema.isSelectable( 'imageBlock' ); // -> true\n\t* schema.isSelectable( 'tableCell' ); // -> true\n\t*\n\t* const text = writer.createText( 'foo' );\n\t* schema.isSelectable( text ); // -> false\n\t* ```\n\t*\n\t* See the {@glink framework/deep-dive/schema#selectable-elements Selectable elements section} of\n\t* the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*/\n\tisSelectable(item) {\n\t\tconst def = this.getDefinition(item);\n\t\tif (!def) return false;\n\t\treturn !!(def.isSelectable || def.isObject);\n\t}\n\t/**\n\t* Returns `true` if the given item is defined to be\n\t* a content by the {@link module:engine/model/schema~ModelSchemaItemDefinition}'s `isContent` property.\n\t*\n\t* ```ts\n\t* schema.isContent( 'paragraph' ); // -> false\n\t* schema.isContent( 'heading1' ); // -> false\n\t* schema.isContent( 'imageBlock' ); // -> true\n\t* schema.isContent( 'horizontalLine' ); // -> true\n\t*\n\t* const text = writer.createText( 'foo' );\n\t* schema.isContent( text ); // -> true\n\t* ```\n\t*\n\t* See the {@glink framework/deep-dive/schema#content-elements Content elements section} of\n\t* the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*/\n\tisContent(item) {\n\t\tconst def = this.getDefinition(item);\n\t\tif (!def) return false;\n\t\treturn !!(def.isContent || def.isObject);\n\t}\n\t/**\n\t* Checks whether the given node can be a child of the given context.\n\t*\n\t* ```ts\n\t* schema.checkChild( model.document.getRoot(), paragraph ); // -> false\n\t*\n\t* schema.register( 'paragraph', {\n\t* \tallowIn: '$root'\n\t* } );\n\t*\n\t* schema.checkChild( model.document.getRoot(), paragraph ); // -> true\n\t* ```\n\t*\n\t* Both {@link module:engine/model/schema~ModelSchema#addChildCheck callback checks} and declarative rules (added when\n\t* {@link module:engine/model/schema~ModelSchema#register registering} and\n\t* {@link module:engine/model/schema~ModelSchema#extend extending} items)\n\t* are evaluated when this method is called.\n\t*\n\t* Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t*\n\t* Note that when verifying whether the given node can be a child of the given context, the schema also verifies the entire\n\t* context &ndash; from its root to its last element. Therefore, it is possible for `checkChild()` to return `false` even though\n\t* the `context` last element can contain the checked child. It happens if one of the `context` elements does not allow its child.\n\t* When `context` is verified, {@link module:engine/model/schema~ModelSchema#addChildCheck custom checks} are considered as well.\n\t*\n\t* @fires checkChild\n\t* @param context The context in which the child will be checked.\n\t* @param def The child to check.\n\t*/\n\tcheckChild(context, def) {\n\t\tif (!def) return false;\n\t\treturn this._checkContextMatch(context, def);\n\t}\n\t/**\n\t* Checks whether the given attribute can be applied in the given context (on the last item of the context).\n\t*\n\t* ```ts\n\t* schema.checkAttribute( textNode, 'bold' ); // -> false\n\t*\n\t* schema.extend( '$text', {\n\t* \tallowAttributes: 'bold'\n\t* } );\n\t*\n\t* schema.checkAttribute( textNode, 'bold' ); // -> true\n\t* ```\n\t*\n\t* Both {@link module:engine/model/schema~ModelSchema#addAttributeCheck callback checks} and declarative rules (added when\n\t* {@link module:engine/model/schema~ModelSchema#register registering} and\n\t* {@link module:engine/model/schema~ModelSchema#extend extending} items)\n\t* are evaluated when this method is called.\n\t*\n\t* Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t*\n\t* @fires checkAttribute\n\t* @param context The context in which the attribute will be checked.\n\t* @param attributeName Name of attribute to check in the given context.\n\t*/\n\tcheckAttribute(context, attributeName) {\n\t\tconst def = this.getDefinition(context.last);\n\t\tif (!def) return false;\n\t\tconst isAllowed = this._evaluateAttributeChecks(context, attributeName);\n\t\treturn isAllowed !== void 0 ? isAllowed : def.allowAttributes.includes(attributeName);\n\t}\n\t/**\n\t* Checks whether the given element (`elementToMerge`) can be merged with the specified base element (`positionOrBaseElement`).\n\t*\n\t* In other words &ndash; both elements are not a limit elements and whether `elementToMerge`'s children\n\t* {@link #checkChild are allowed} in the `positionOrBaseElement`.\n\t*\n\t* This check ensures that elements merged with {@link module:engine/model/writer~ModelWriter#merge `Writer#merge()`}\n\t* will be valid.\n\t*\n\t* Instead of elements, you can pass the instance of the {@link module:engine/model/position~ModelPosition} class as the\n\t* `positionOrBaseElement`. It means that the elements before and after the position will be checked whether they can be merged.\n\t*\n\t* @param positionOrBaseElement The position or base element to which the `elementToMerge` will be merged.\n\t* @param elementToMerge The element to merge. Required if `positionOrBaseElement` is an element.\n\t*/\n\tcheckMerge(positionOrBaseElement, elementToMerge) {\n\t\tif (positionOrBaseElement instanceof ModelPosition) {\n\t\t\tconst nodeBefore = positionOrBaseElement.nodeBefore;\n\t\t\tconst nodeAfter = positionOrBaseElement.nodeAfter;\n\t\t\tif (!(nodeBefore instanceof ModelElement))\n /**\n\t\t\t* The node before the merge position must be an element.\n\t\t\t*\n\t\t\t* @error schema-check-merge-no-element-before\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"schema-check-merge-no-element-before\", this);\n\t\t\tif (!(nodeAfter instanceof ModelElement))\n /**\n\t\t\t* The node after the merge position must be an element.\n\t\t\t*\n\t\t\t* @error schema-check-merge-no-element-after\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"schema-check-merge-no-element-after\", this);\n\t\t\treturn this.checkMerge(nodeBefore, nodeAfter);\n\t\t}\n\t\tif (this.isLimit(positionOrBaseElement) || this.isLimit(elementToMerge)) return false;\n\t\tfor (const child of elementToMerge.getChildren()) if (!this.checkChild(positionOrBaseElement, child)) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Allows registering a callback to the {@link #checkChild} method calls.\n\t*\n\t* Callbacks allow you to implement rules which are not otherwise possible to achieve\n\t* by using the declarative API of {@link module:engine/model/schema~ModelSchemaItemDefinition}.\n\t*\n\t* Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t*\n\t* For example, by using this method you can disallow elements in specific contexts:\n\t*\n\t* ```ts\n\t* // Disallow `heading1` inside a `blockQuote` that is inside a table.\n\t* schema.addChildCheck( ( context, childDefinition ) => {\n\t* \tif ( context.endsWith( 'tableCell blockQuote' ) ) {\n\t* \t\treturn false;\n\t* \t}\n\t* }, 'heading1' );\n\t* ```\n\t*\n\t* You can skip the optional `itemName` parameter to evaluate the callback for every `checkChild()` call.\n\t*\n\t* ```ts\n\t* // Inside specific custom element, allow only children, which allows for a specific attribute.\n\t* schema.addChildCheck( ( context, childDefinition ) => {\n\t* \tif ( context.endsWith( 'myElement' ) ) {\n\t* \t\treturn childDefinition.allowAttributes.includes( 'myAttribute' );\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* Please note that the generic callbacks may affect the editor performance and should be avoided if possible.\n\t*\n\t* When one of the callbacks makes a decision (returns `true` or `false`) the processing is finished and other callbacks are not fired.\n\t* Callbacks are fired in the order they were added, however generic callbacks are fired before callbacks added for a specified item.\n\t*\n\t* You can also use `checkChild` event, if you need even better control. The result from the example above could also be\n\t* achieved with following event callback:\n\t*\n\t* ```ts\n\t* schema.on( 'checkChild', ( evt, args ) => {\n\t* \tconst context = args[ 0 ];\n\t* \tconst childDefinition = args[ 1 ];\n\t*\n\t* \tif ( context.endsWith( 'myElement' ) ) {\n\t* \t\t// Prevent next listeners from being called.\n\t* \t\tevt.stop();\n\t* \t\t// Set the `checkChild()` return value.\n\t* \t\tevt.return = childDefinition.allowAttributes.includes( 'myAttribute' );\n\t* \t}\n\t* }, { priority: 'high' } );\n\t* ```\n\t*\n\t* Note that the callback checks and declarative rules checks are processed on `normal` priority.\n\t*\n\t* Adding callbacks this way can also negatively impact editor performance.\n\t*\n\t* @param callback The callback to be called. It is called with two parameters:\n\t* {@link module:engine/model/schema~ModelSchemaContext} (context) instance and\n\t* {@link module:engine/model/schema~ModelSchemaCompiledItemDefinition} (definition). The callback may return `true/false` to\n\t* override `checkChild()`'s return value. If it does not return a boolean value, the default algorithm (or other callbacks) will define\n\t* `checkChild()`'s return value.\n\t* @param itemName Name of the schema item for which the callback is registered. If specified, the callback will be run only for\n\t* `checkChild()` calls which `def` parameter matches the `itemName`. Otherwise, the callback will run for every `checkChild` call.\n\t*/\n\taddChildCheck(callback, itemName) {\n\t\tconst key = itemName !== void 0 ? itemName : this._genericCheckSymbol;\n\t\tconst checks = this._customChildChecks.get(key) || [];\n\t\tchecks.push(callback);\n\t\tthis._customChildChecks.set(key, checks);\n\t}\n\t/**\n\t* Allows registering a callback to the {@link #checkAttribute} method calls.\n\t*\n\t* Callbacks allow you to implement rules which are not otherwise possible to achieve\n\t* by using the declarative API of {@link module:engine/model/schema~ModelSchemaItemDefinition}.\n\t*\n\t* Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t*\n\t* For example, by using this method you can disallow setting attributes on nodes in specific contexts:\n\t*\n\t* ```ts\n\t* // Disallow setting `bold` on text inside `heading1` element:\n\t* schema.addAttributeCheck( context => {\n\t* \tif ( context.endsWith( 'heading1 $text' ) ) {\n\t* \t\treturn false;\n\t* \t}\n\t* }, 'bold' );\n\t* ```\n\t*\n\t* You can skip the optional `attributeName` parameter to evaluate the callback for every `checkAttribute()` call.\n\t*\n\t* ```ts\n\t* // Disallow formatting attributes on text inside custom `myTitle` element:\n\t* schema.addAttributeCheck( ( context, attributeName ) => {\n\t* \tif ( context.endsWith( 'myTitle $text' ) && schema.getAttributeProperties( attributeName ).isFormatting ) {\n\t* \t\treturn false;\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* Please note that the generic callbacks may affect the editor performance and should be avoided if possible.\n\t*\n\t* When one of the callbacks makes a decision (returns `true` or `false`) the processing is finished and other callbacks are not fired.\n\t* Callbacks are fired in the order they were added, however generic callbacks are fired before callbacks added for a specified item.\n\t*\n\t* You can also use {@link #event:checkAttribute} event, if you need even better control. The result from the example above could also\n\t* be achieved with following event callback:\n\t*\n\t* ```ts\n\t* schema.on( 'checkAttribute', ( evt, args ) => {\n\t* \tconst context = args[ 0 ];\n\t* \tconst attributeName = args[ 1 ];\n\t*\n\t* \tif ( context.endsWith( 'myTitle $text' ) && schema.getAttributeProperties( attributeName ).isFormatting ) {\n\t* \t\t// Prevent next listeners from being called.\n\t* \t\tevt.stop();\n\t* \t\t// Set the `checkAttribute()` return value.\n\t* \t\tevt.return = false;\n\t* \t}\n\t* }, { priority: 'high' } );\n\t* ```\n\t*\n\t* Note that the callback checks and declarative rules checks are processed on `normal` priority.\n\t*\n\t* Adding callbacks this way can also negatively impact editor performance.\n\t*\n\t* @param callback The callback to be called. It is called with two parameters:\n\t* {@link module:engine/model/schema~ModelSchemaContext `context`} and attribute name. The callback may return `true` or `false`, to\n\t* override `checkAttribute()`'s return value. If it does not return a boolean value, the default algorithm (or other callbacks)\n\t* will define `checkAttribute()`'s return value.\n\t* @param attributeName Name of the attribute for which the callback is registered. If specified, the callback will be run only for\n\t* `checkAttribute()` calls with matching `attributeName`. Otherwise, the callback will run for every `checkAttribute()` call.\n\t*/\n\taddAttributeCheck(callback, attributeName) {\n\t\tconst key = attributeName !== void 0 ? attributeName : this._genericCheckSymbol;\n\t\tconst checks = this._customAttributeChecks.get(key) || [];\n\t\tchecks.push(callback);\n\t\tthis._customAttributeChecks.set(key, checks);\n\t}\n\t/**\n\t* This method allows assigning additional metadata to the model attributes. For example,\n\t* {@link module:engine/model/schema~ModelAttributeProperties `AttributeProperties#isFormatting` property} is\n\t* used to mark formatting attributes (like `bold` or `italic`).\n\t*\n\t* ```ts\n\t* // Mark bold as a formatting attribute.\n\t* schema.setAttributeProperties( 'bold', {\n\t* \tisFormatting: true\n\t* } );\n\t*\n\t* // Override code not to be considered a formatting markup.\n\t* schema.setAttributeProperties( 'code', {\n\t* \tisFormatting: false\n\t* } );\n\t* ```\n\t*\n\t* Properties are not limited to members defined in the\n\t* {@link module:engine/model/schema~ModelAttributeProperties `AttributeProperties` type} and you can also use custom properties:\n\t*\n\t* ```ts\n\t* schema.setAttributeProperties( 'blockQuote', {\n\t* \tcustomProperty: 'value'\n\t* } );\n\t* ```\n\t*\n\t* Subsequent calls with the same attribute will extend its custom properties:\n\t*\n\t* ```ts\n\t* schema.setAttributeProperties( 'blockQuote', {\n\t* \tone: 1\n\t* } );\n\t*\n\t* schema.setAttributeProperties( 'blockQuote', {\n\t* \ttwo: 2\n\t* } );\n\t*\n\t* console.log( schema.getAttributeProperties( 'blockQuote' ) );\n\t* // Logs: { one: 1, two: 2 }\n\t* ```\n\t*\n\t* @param attributeName A name of the attribute to receive the properties.\n\t* @param properties A dictionary of properties.\n\t*/\n\tsetAttributeProperties(attributeName, properties) {\n\t\tthis._attributeProperties[attributeName] = Object.assign(this.getAttributeProperties(attributeName), properties);\n\t}\n\t/**\n\t* Returns properties associated with a given model attribute. See {@link #setAttributeProperties `setAttributeProperties()`}.\n\t*\n\t* @param attributeName A name of the attribute.\n\t*/\n\tgetAttributeProperties(attributeName) {\n\t\treturn this._attributeProperties[attributeName] || Object.create(null);\n\t}\n\t/**\n\t* Returns the lowest {@link module:engine/model/schema~ModelSchema#isLimit limit element} containing the entire\n\t* selection/range/position or the root otherwise.\n\t*\n\t* @param selectionOrRangeOrPosition The selection/range/position to check.\n\t* @returns The lowest limit element containing the entire `selectionOrRangeOrPosition`.\n\t*/\n\tgetLimitElement(selectionOrRangeOrPosition) {\n\t\tlet element;\n\t\tif (selectionOrRangeOrPosition instanceof ModelPosition) element = selectionOrRangeOrPosition.parent;\n\t\telse element = (selectionOrRangeOrPosition instanceof ModelRange ? [selectionOrRangeOrPosition] : Array.from(selectionOrRangeOrPosition.getRanges())).reduce((element, range) => {\n\t\t\tconst rangeCommonAncestor = range.getCommonAncestor();\n\t\t\tif (!element) return rangeCommonAncestor;\n\t\t\treturn element.getCommonAncestor(rangeCommonAncestor, { includeSelf: true });\n\t\t}, null);\n\t\twhile (!this.isLimit(element)) if (element.parent) element = element.parent;\n\t\telse break;\n\t\treturn element;\n\t}\n\t/**\n\t* Checks whether the attribute is allowed in selection:\n\t*\n\t* * if the selection is not collapsed, then checks if the attribute is allowed on any of nodes in that range,\n\t* * if the selection is collapsed, then checks if on the selection position there's a text with the\n\t* specified attribute allowed.\n\t*\n\t* @param selection Selection which will be checked.\n\t* @param attribute The name of the attribute to check.\n\t*/\n\tcheckAttributeInSelection(selection, attribute) {\n\t\tif (selection.isCollapsed) {\n\t\t\tconst context = [...selection.getFirstPosition().getAncestors(), new ModelText(\"\", selection.getAttributes())];\n\t\t\treturn this.checkAttribute(context, attribute);\n\t\t} else {\n\t\t\tconst ranges = selection.getRanges();\n\t\t\tfor (const range of ranges) for (const value of range) if (this.checkAttribute(value.item, attribute)) return true;\n\t\t}\n\t\treturn false;\n\t}\n\t/**\n\t* Transforms the given set of ranges into a set of ranges where the given attribute is allowed (and can be applied).\n\t*\n\t* @param ranges Ranges to be validated.\n\t* @param attribute The name of the attribute to check.\n\t* @param options Optional configuration.\n\t* @param options.includeEmptyRanges When `true`, empty ranges that allow the attribute are also included\n\t* in the returned ranges.\n\t* @returns Ranges in which the attribute is allowed.\n\t*/\n\t*getValidRanges(ranges, attribute, options = {}) {\n\t\tranges = convertToMinimalFlatRanges(ranges);\n\t\tfor (const range of ranges) yield* this._getValidRangesForRange(range, attribute, options);\n\t}\n\t/**\n\t* Basing on given `position`, finds and returns a {@link module:engine/model/range~ModelRange range} which is\n\t* nearest to that `position` and is a correct range for selection.\n\t*\n\t* The correct selection range might be collapsed when it is located in a position where the text node can be placed.\n\t* Non-collapsed range is returned when selection can be placed around element marked as an \"object\" in\n\t* the {@link module:engine/model/schema~ModelSchema schema}.\n\t*\n\t* Direction of searching for the nearest correct selection range can be specified as:\n\t*\n\t* * `both` - searching will be performed in both ways,\n\t* * `forward` - searching will be performed only forward,\n\t* * `backward` - searching will be performed only backward.\n\t*\n\t* When valid selection range cannot be found, `null` is returned.\n\t*\n\t* @param position Reference position where new selection range should be looked for.\n\t* @param direction Search direction.\n\t* @returns Nearest selection range or `null` if one cannot be found.\n\t*/\n\tgetNearestSelectionRange(position, direction = \"both\") {\n\t\tif (position.root.rootName == \"$graveyard\") return null;\n\t\tif (this.checkChild(position, \"$text\")) return new ModelRange(position);\n\t\tlet backwardWalker, forwardWalker;\n\t\tconst limitElement = position.getAncestors().reverse().find((item) => this.isLimit(item)) || position.root;\n\t\tif (direction == \"both\" || direction == \"backward\") backwardWalker = new ModelTreeWalker({\n\t\t\tboundaries: ModelRange._createIn(limitElement),\n\t\t\tstartPosition: position,\n\t\t\tdirection: \"backward\"\n\t\t});\n\t\tif (direction == \"both\" || direction == \"forward\") forwardWalker = new ModelTreeWalker({\n\t\t\tboundaries: ModelRange._createIn(limitElement),\n\t\t\tstartPosition: position\n\t\t});\n\t\tfor (const data of combineWalkers(backwardWalker, forwardWalker)) {\n\t\t\tconst type = data.walker == backwardWalker ? \"elementEnd\" : \"elementStart\";\n\t\t\tconst value = data.value;\n\t\t\tif (value.type == type && this.isObject(value.item)) return ModelRange._createOn(value.item);\n\t\t\tif (this.checkChild(value.nextPosition, \"$text\")) return new ModelRange(value.nextPosition);\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Tries to find position ancestors that allow to insert a given node.\n\t* It starts searching from the given position and goes node by node to the top of the model tree\n\t* as long as a {@link module:engine/model/schema~ModelSchema#isLimit limit element}, an\n\t* {@link module:engine/model/schema~ModelSchema#isObject object element} or a topmost ancestor is not reached.\n\t*\n\t* @param position The position that the search will start from.\n\t* @param node The node for which an allowed parent should be found or its name.\n\t* @returns Allowed parent or null if nothing was found.\n\t*/\n\tfindAllowedParent(position, node) {\n\t\tlet parent = position.parent;\n\t\twhile (parent) {\n\t\t\tif (this.checkChild(parent, node)) return parent;\n\t\t\tif (this.isLimit(parent)) return null;\n\t\t\tparent = parent.parent;\n\t\t}\n\t\treturn null;\n\t}\n\t/**\n\t* Sets attributes allowed by the schema on a given node.\n\t*\n\t* @param node A node to set attributes on.\n\t* @param attributes Attributes keys and values.\n\t* @param writer An instance of the model writer.\n\t*/\n\tsetAllowedAttributes(node, attributes, writer) {\n\t\tconst model = writer.model;\n\t\tfor (const [attributeName, attributeValue] of Object.entries(attributes)) if (model.schema.checkAttribute(node, attributeName)) writer.setAttribute(attributeName, attributeValue, node);\n\t}\n\t/**\n\t* Removes attributes disallowed by the schema.\n\t*\n\t* @param nodes Nodes that will be filtered.\n\t*/\n\tremoveDisallowedAttributes(nodes, writer) {\n\t\tfor (const node of nodes) if (node.is(\"$text\")) removeDisallowedAttributeFromNode(this, node, writer);\n\t\telse {\n\t\t\tconst positionsInRange = ModelRange._createIn(node).getPositions();\n\t\t\tfor (const position of positionsInRange) {\n\t\t\t\tconst item = position.nodeBefore || position.parent;\n\t\t\t\tremoveDisallowedAttributeFromNode(this, item, writer);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* Gets attributes of a node that have a given property.\n\t*\n\t* @param node Node to get attributes from.\n\t* @param propertyName Name of the property that attribute must have to return it.\n\t* @param propertyValue Desired value of the property that we want to check.\n\t* When `undefined` attributes will be returned if they have set a given property no matter what the value is. If specified it will\n\t* return attributes which given property's value is equal to this parameter.\n\t* @returns Object with attributes' names as key and attributes' values as value.\n\t*/\n\tgetAttributesWithProperty(node, propertyName, propertyValue) {\n\t\tconst attributes = {};\n\t\tfor (const [attributeName, attributeValue] of node.getAttributes()) {\n\t\t\tconst attributeProperties = this.getAttributeProperties(attributeName);\n\t\t\tif (attributeProperties[propertyName] === void 0) continue;\n\t\t\tif (propertyValue === void 0 || propertyValue === attributeProperties[propertyName]) attributes[attributeName] = attributeValue;\n\t\t}\n\t\treturn attributes;\n\t}\n\t/**\n\t* Creates an instance of the schema context.\n\t*/\n\tcreateContext(context) {\n\t\treturn new ModelSchemaContext(context);\n\t}\n\t_clearCache() {\n\t\tthis._compiledDefinitions = null;\n\t}\n\t_compile() {\n\t\tconst definitions = {};\n\t\tconst sourceRules = this._sourceDefinitions;\n\t\tconst itemNames = Object.keys(sourceRules);\n\t\tfor (const itemName of itemNames) definitions[itemName] = compileBaseItemRule(sourceRules[itemName], itemName);\n\t\tconst items = Object.values(definitions);\n\t\tfor (const item of items) {\n\t\t\tpropagateAllowIn(definitions, item);\n\t\t\tpropagateAllowChildren(definitions, item);\n\t\t\tpropagateDisallowIn(definitions, item);\n\t\t\tpropagateDisallowChildren(definitions, item);\n\t\t}\n\t\tfor (const item of items) resolveDisallows(definitions, item);\n\t\tfor (const item of items) compileAllowContentOf(definitions, item);\n\t\tfor (const item of items) compileAllowWhere(definitions, item);\n\t\tfor (const item of items) compileAllowAttributesOf(definitions, item);\n\t\tfor (const item of items) compileInheritPropertiesFrom(definitions, item);\n\t\tthis._compiledDefinitions = compileDefinitions(definitions);\n\t}\n\t_checkContextMatch(context, def) {\n\t\tconst parentItem = context.last;\n\t\tlet isAllowed = this._evaluateChildChecks(context, def);\n\t\tisAllowed = isAllowed !== void 0 ? isAllowed : def.allowIn.includes(parentItem.name);\n\t\tif (!isAllowed) return false;\n\t\tconst parentItemDefinition = this.getDefinition(parentItem);\n\t\tconst parentContext = context.trimLast();\n\t\tif (!parentItemDefinition) return false;\n\t\tif (parentContext.length == 0) return true;\n\t\treturn this._checkContextMatch(parentContext, parentItemDefinition);\n\t}\n\t/**\n\t* Calls child check callbacks to decide whether `def` is allowed in `context`. It uses both generic and specific (defined for `def`\n\t* item) callbacks. If neither callback makes a decision, `undefined` is returned.\n\t*\n\t* Note that the first callback that makes a decision \"wins\", i.e., if any callback returns `true` or `false`, then the processing\n\t* is over and that result is returned.\n\t*/\n\t_evaluateChildChecks(context, def) {\n\t\tconst genericChecks = this._customChildChecks.get(this._genericCheckSymbol) || [];\n\t\tconst childChecks = this._customChildChecks.get(def.name) || [];\n\t\tfor (const check of [...genericChecks, ...childChecks]) {\n\t\t\tconst result = check(context, def);\n\t\t\tif (result !== void 0) return result;\n\t\t}\n\t}\n\t/**\n\t* Calls attribute check callbacks to decide whether `attributeName` can be set on the last element of `context`. It uses both\n\t* generic and specific (defined for `attributeName`) callbacks. If neither callback makes a decision, `undefined` is returned.\n\t*\n\t* Note that the first callback that makes a decision \"wins\", i.e., if any callback returns `true` or `false`, then the processing\n\t* is over and that result is returned.\n\t*/\n\t_evaluateAttributeChecks(context, attributeName) {\n\t\tconst genericChecks = this._customAttributeChecks.get(this._genericCheckSymbol) || [];\n\t\tconst childChecks = this._customAttributeChecks.get(attributeName) || [];\n\t\tfor (const check of [...genericChecks, ...childChecks]) {\n\t\t\tconst result = check(context, attributeName);\n\t\t\tif (result !== void 0) return result;\n\t\t}\n\t}\n\t/**\n\t* Takes a flat range and an attribute name. Traverses the range recursively and deeply to find and return all ranges\n\t* inside the given range on which the attribute can be applied.\n\t*\n\t* This is a helper function for {@link ~ModelSchema#getValidRanges}.\n\t*\n\t* @param range The range to process.\n\t* @param attribute The name of the attribute to check.\n\t* @returns Ranges in which the attribute is allowed.\n\t*/\n\t*_getValidRangesForRange(range, attribute, options) {\n\t\tlet start = range.start;\n\t\tlet end = range.start;\n\t\tfor (const item of range.getItems({ shallow: true })) {\n\t\t\tif (item.is(\"element\")) if (options.includeEmptyRanges && item.isEmpty) {\n\t\t\t\tconst context = this.createContext(item);\n\t\t\t\tif (this.checkChild(context, \"$text\") && this.checkAttribute(context.push(\"$text\"), attribute)) yield ModelRange._createIn(item);\n\t\t\t} else yield* this._getValidRangesForRange(ModelRange._createIn(item), attribute, options);\n\t\t\tif (!this.checkAttribute(item, attribute)) {\n\t\t\t\tif (!start.isEqual(end)) yield new ModelRange(start, end);\n\t\t\t\tstart = ModelPosition._createAfter(item);\n\t\t\t}\n\t\t\tend = ModelPosition._createAfter(item);\n\t\t}\n\t\tif (!start.isEqual(end)) yield new ModelRange(start, end);\n\t}\n\t/**\n\t* Returns a model range which is optimal (in terms of UX) for inserting a widget block.\n\t*\n\t* For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph\n\t* will be returned so that it is not split. If the selection is at the end of a paragraph,\n\t* the collapsed range after this paragraph will be returned.\n\t*\n\t* Note: If the selection is placed in an empty block, the range in that block will be returned. If that range\n\t* is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced\n\t* by the inserted widget block.\n\t*\n\t* @internal\n\t* @param selection The selection based on which the insertion position should be calculated.\n\t* @param place The place where to look for optimal insertion range.\n\t* The `auto` value will determine itself the best position for insertion.\n\t* The `before` value will try to find a position before selection.\n\t* The `after` value will try to find a position after selection.\n\t* @returns The optimal range.\n\t*/\n\tfindOptimalInsertionRange(selection, place) {\n\t\tconst selectedElement = selection.getSelectedElement();\n\t\tif (selectedElement && this.isObject(selectedElement) && !this.isInline(selectedElement)) {\n\t\t\tif (place == \"before\" || place == \"after\") return new ModelRange(ModelPosition._createAt(selectedElement, place));\n\t\t\treturn ModelRange._createOn(selectedElement);\n\t\t}\n\t\tconst firstBlock = first(selection.getSelectedBlocks());\n\t\tif (!firstBlock) return new ModelRange(selection.focus);\n\t\tif (firstBlock.isEmpty) return new ModelRange(ModelPosition._createAt(firstBlock, 0));\n\t\tconst positionAfter = ModelPosition._createAfter(firstBlock);\n\t\tif (selection.focus.isTouching(positionAfter)) return new ModelRange(positionAfter);\n\t\treturn new ModelRange(ModelPosition._createBefore(firstBlock));\n\t}\n};\n/**\n* A schema context &ndash; a list of ancestors of a given position in the document.\n*\n* Considering such position:\n*\n* ```xml\n* <$root>\n* \t<blockQuote>\n* \t\t<paragraph>\n* \t\t\t^\n* \t\t</paragraph>\n* \t</blockQuote>\n* </$root>\n* ```\n*\n* The context of this position is its {@link module:engine/model/position~ModelPosition#getAncestors lists of ancestors}:\n*\n*\t\t[ rootElement, blockQuoteElement, paragraphElement ]\n*\n* Contexts are used in the {@link module:engine/model/schema~ModelSchema#event:checkChild `Schema#checkChild`} and\n* {@link module:engine/model/schema~ModelSchema#event:checkAttribute `Schema#checkAttribute`} events as a definition\n* of a place in the document where the check occurs. The context instances are created based on the first arguments\n* of the {@link module:engine/model/schema~ModelSchema#checkChild `Schema#checkChild()`} and\n* {@link module:engine/model/schema~ModelSchema#checkAttribute `Schema#checkAttribute()`} methods so when\n* using these methods you need to use {@link module:engine/model/schema~ModelSchemaContextDefinition}s.\n*/\nvar ModelSchemaContext = class ModelSchemaContext {\n\t_items;\n\t/**\n\t* Creates an instance of the context.\n\t*/\n\tconstructor(context) {\n\t\tif (context instanceof ModelSchemaContext) return context;\n\t\tlet items;\n\t\tif (typeof context == \"string\") items = [context];\n\t\telse if (!Array.isArray(context)) items = context.getAncestors({ includeSelf: true });\n\t\telse items = context;\n\t\tthis._items = items.map(mapContextItem);\n\t}\n\t/**\n\t* The number of items.\n\t*/\n\tget length() {\n\t\treturn this._items.length;\n\t}\n\t/**\n\t* The last item (the lowest node).\n\t*/\n\tget last() {\n\t\treturn this._items[this._items.length - 1];\n\t}\n\t/**\n\t* Iterable interface.\n\t*\n\t* Iterates over all context items.\n\t*/\n\t[Symbol.iterator]() {\n\t\treturn this._items[Symbol.iterator]();\n\t}\n\t/**\n\t* Returns a new schema context instance with an additional item.\n\t*\n\t* Item can be added as:\n\t*\n\t* ```ts\n\t* const context = new ModelSchemaContext( [ '$root' ] );\n\t*\n\t* // An element.\n\t* const fooElement = writer.createElement( 'fooElement' );\n\t* const newContext = context.push( fooElement ); // [ '$root', 'fooElement' ]\n\t*\n\t* // A text node.\n\t* const text = writer.createText( 'foobar' );\n\t* const newContext = context.push( text ); // [ '$root', '$text' ]\n\t*\n\t* // A string (element name).\n\t* const newContext = context.push( 'barElement' ); // [ '$root', 'barElement' ]\n\t* ```\n\t*\n\t* **Note** {@link module:engine/model/node~ModelNode} that is already in the model tree will be added as the only item\n\t* (without ancestors).\n\t*\n\t* @param item An item that will be added to the current context.\n\t* @returns A new schema context instance with an additional item.\n\t*/\n\tpush(item) {\n\t\tconst ctx = new ModelSchemaContext([item]);\n\t\tctx._items = [...this._items, ...ctx._items];\n\t\treturn ctx;\n\t}\n\t/**\n\t* Returns a new schema context that is based on this context but has the last item removed.\n\t*\n\t* ```ts\n\t* const ctxParagraph = new ModelSchemaContext( [ '$root', 'blockQuote', 'paragraph' ] );\n\t* const ctxBlockQuote = ctxParagraph.trimLast(); // Items in `ctxBlockQuote` are: `$root` an `blockQuote`.\n\t* const ctxRoot = ctxBlockQuote.trimLast(); // Items in `ctxRoot` are: `$root`.\n\t* ```\n\t*\n\t* @returns A new reduced schema context instance.\n\t*/\n\ttrimLast() {\n\t\tconst ctx = new ModelSchemaContext([]);\n\t\tctx._items = this._items.slice(0, -1);\n\t\treturn ctx;\n\t}\n\t/**\n\t* Gets an item on the given index.\n\t*/\n\tgetItem(index) {\n\t\treturn this._items[index];\n\t}\n\t/**\n\t* Returns the names of items.\n\t*/\n\t*getNames() {\n\t\tyield* this._items.map((item) => item.name);\n\t}\n\t/**\n\t* Checks whether the context ends with the given nodes.\n\t*\n\t* ```ts\n\t* const ctx = new ModelSchemaContext( [ rootElement, paragraphElement, textNode ] );\n\t*\n\t* ctx.endsWith( '$text' ); // -> true\n\t* ctx.endsWith( 'paragraph $text' ); // -> true\n\t* ctx.endsWith( '$root' ); // -> false\n\t* ctx.endsWith( 'paragraph' ); // -> false\n\t* ```\n\t*/\n\tendsWith(query) {\n\t\treturn Array.from(this.getNames()).join(\" \").endsWith(query);\n\t}\n\t/**\n\t* Checks whether the context starts with the given nodes.\n\t*\n\t* ```ts\n\t* const ctx = new ModelSchemaContext( [ rootElement, paragraphElement, textNode ] );\n\t*\n\t* ctx.endsWith( '$root' ); // -> true\n\t* ctx.endsWith( '$root paragraph' ); // -> true\n\t* ctx.endsWith( '$text' ); // -> false\n\t* ctx.endsWith( 'paragraph' ); // -> false\n\t* ```\n\t*/\n\tstartsWith(query) {\n\t\treturn Array.from(this.getNames()).join(\" \").startsWith(query);\n\t}\n};\nfunction compileBaseItemRule(sourceItemRules, itemName) {\n\tconst itemRule = {\n\t\tname: itemName,\n\t\tallowIn: /* @__PURE__ */ new Set(),\n\t\tallowChildren: /* @__PURE__ */ new Set(),\n\t\tdisallowIn: /* @__PURE__ */ new Set(),\n\t\tdisallowChildren: /* @__PURE__ */ new Set(),\n\t\tallowContentOf: /* @__PURE__ */ new Set(),\n\t\tallowWhere: /* @__PURE__ */ new Set(),\n\t\tallowAttributes: /* @__PURE__ */ new Set(),\n\t\tdisallowAttributes: /* @__PURE__ */ new Set(),\n\t\tallowAttributesOf: /* @__PURE__ */ new Set(),\n\t\tinheritTypesFrom: /* @__PURE__ */ new Set()\n\t};\n\tcopyTypes(sourceItemRules, itemRule);\n\tcopyProperty(sourceItemRules, itemRule, \"allowIn\");\n\tcopyProperty(sourceItemRules, itemRule, \"allowChildren\");\n\tcopyProperty(sourceItemRules, itemRule, \"disallowIn\");\n\tcopyProperty(sourceItemRules, itemRule, \"disallowChildren\");\n\tcopyProperty(sourceItemRules, itemRule, \"allowContentOf\");\n\tcopyProperty(sourceItemRules, itemRule, \"allowWhere\");\n\tcopyProperty(sourceItemRules, itemRule, \"allowAttributes\");\n\tcopyProperty(sourceItemRules, itemRule, \"disallowAttributes\");\n\tcopyProperty(sourceItemRules, itemRule, \"allowAttributesOf\");\n\tcopyProperty(sourceItemRules, itemRule, \"inheritTypesFrom\");\n\tresolveInheritAll(sourceItemRules, itemRule);\n\treturn itemRule;\n}\nfunction propagateAllowIn(definitions, item) {\n\tfor (const parentName of item.allowIn) {\n\t\tconst parentItem = definitions[parentName];\n\t\tif (parentItem) parentItem.allowChildren.add(item.name);\n\t\telse item.allowIn.delete(parentName);\n\t}\n}\nfunction propagateAllowChildren(definitions, item) {\n\tfor (const childName of item.allowChildren) {\n\t\tconst childItem = definitions[childName];\n\t\tif (childItem) childItem.allowIn.add(item.name);\n\t\telse item.allowChildren.delete(childName);\n\t}\n}\nfunction propagateDisallowIn(definitions, item) {\n\tfor (const parentName of item.disallowIn) {\n\t\tconst parentItem = definitions[parentName];\n\t\tif (parentItem) parentItem.disallowChildren.add(item.name);\n\t\telse item.disallowIn.delete(parentName);\n\t}\n}\nfunction propagateDisallowChildren(definitions, item) {\n\tfor (const childName of item.disallowChildren) {\n\t\tconst childItem = definitions[childName];\n\t\tif (childItem) childItem.disallowIn.add(item.name);\n\t\telse item.disallowChildren.delete(childName);\n\t}\n}\nfunction resolveDisallows(definitions, item) {\n\tfor (const childName of item.disallowChildren) item.allowChildren.delete(childName);\n\tfor (const parentName of item.disallowIn) item.allowIn.delete(parentName);\n\tfor (const attributeName of item.disallowAttributes) item.allowAttributes.delete(attributeName);\n}\nfunction compileAllowContentOf(definitions, item) {\n\tfor (const allowContentOfItemName of item.allowContentOf) {\n\t\tconst baseItem = definitions[allowContentOfItemName];\n\t\tif (!baseItem) continue;\n\t\tbaseItem.disallowChildren.forEach((childName) => {\n\t\t\tif (item.allowChildren.has(childName)) return;\n\t\t\titem.disallowChildren.add(childName);\n\t\t\tdefinitions[childName].disallowIn.add(item.name);\n\t\t});\n\t\tbaseItem.allowChildren.forEach((childName) => {\n\t\t\tif (item.disallowChildren.has(childName)) return;\n\t\t\titem.allowChildren.add(childName);\n\t\t\tdefinitions[childName].allowIn.add(item.name);\n\t\t});\n\t}\n}\nfunction compileAllowWhere(definitions, item) {\n\tfor (const allowWhereItemName of item.allowWhere) {\n\t\tconst baseItem = definitions[allowWhereItemName];\n\t\tif (!baseItem) continue;\n\t\tbaseItem.disallowIn.forEach((parentName) => {\n\t\t\tif (item.allowIn.has(parentName)) return;\n\t\t\titem.disallowIn.add(parentName);\n\t\t\tdefinitions[parentName].disallowChildren.add(item.name);\n\t\t});\n\t\tbaseItem.allowIn.forEach((parentName) => {\n\t\t\tif (item.disallowIn.has(parentName)) return;\n\t\t\titem.allowIn.add(parentName);\n\t\t\tdefinitions[parentName].allowChildren.add(item.name);\n\t\t});\n\t}\n}\nfunction compileDefinitions(definitions) {\n\tconst finalDefinitions = {};\n\tfor (const item of Object.values(definitions)) finalDefinitions[item.name] = {\n\t\tname: item.name,\n\t\tisBlock: !!item.isBlock,\n\t\tisContent: !!item.isContent,\n\t\tisInline: !!item.isInline,\n\t\tisLimit: !!item.isLimit,\n\t\tisObject: !!item.isObject,\n\t\tisSelectable: !!item.isSelectable,\n\t\tallowIn: Array.from(item.allowIn).filter((name) => !!definitions[name]),\n\t\tallowChildren: Array.from(item.allowChildren).filter((name) => !!definitions[name]),\n\t\tallowAttributes: Array.from(item.allowAttributes)\n\t};\n\treturn finalDefinitions;\n}\nfunction compileAllowAttributesOf(definitions, item) {\n\tfor (const allowAttributeOfItemName of item.allowAttributesOf) {\n\t\tconst baseItem = definitions[allowAttributeOfItemName];\n\t\tif (!baseItem) return;\n\t\tbaseItem.allowAttributes.forEach((attributeName) => {\n\t\t\tif (item.disallowAttributes.has(attributeName)) return;\n\t\t\titem.allowAttributes.add(attributeName);\n\t\t});\n\t}\n}\nfunction compileInheritPropertiesFrom(definitions, item) {\n\tfor (const inheritPropertiesOfItemName of item.inheritTypesFrom) {\n\t\tconst inheritFrom = definitions[inheritPropertiesOfItemName];\n\t\tif (inheritFrom) {\n\t\t\tconst typeNames = Object.keys(inheritFrom).filter((name) => name.startsWith(\"is\"));\n\t\t\tfor (const name of typeNames) if (!(name in item)) item[name] = inheritFrom[name];\n\t\t}\n\t}\n}\nfunction copyTypes(sourceItemRules, itemRule) {\n\tfor (const sourceItemRule of sourceItemRules) {\n\t\tconst typeNames = Object.keys(sourceItemRule).filter((name) => name.startsWith(\"is\"));\n\t\tfor (const name of typeNames) itemRule[name] = !!sourceItemRule[name];\n\t}\n}\nfunction copyProperty(sourceItemRules, itemRule, propertyName) {\n\tfor (const sourceItemRule of sourceItemRules) {\n\t\tlet value = sourceItemRule[propertyName];\n\t\tif (typeof value == \"string\") value = [value];\n\t\tif (Array.isArray(value)) value.forEach((singleValue) => itemRule[propertyName].add(singleValue));\n\t}\n}\nfunction resolveInheritAll(sourceItemRules, itemRule) {\n\tfor (const sourceItemRule of sourceItemRules) {\n\t\tconst inheritFrom = sourceItemRule.inheritAllFrom;\n\t\tif (inheritFrom) {\n\t\t\titemRule.allowContentOf.add(inheritFrom);\n\t\t\titemRule.allowWhere.add(inheritFrom);\n\t\t\titemRule.allowAttributesOf.add(inheritFrom);\n\t\t\titemRule.inheritTypesFrom.add(inheritFrom);\n\t\t}\n\t}\n}\nfunction mapContextItem(ctxItem) {\n\tif (typeof ctxItem == \"string\" || ctxItem.is(\"documentFragment\")) return {\n\t\tname: typeof ctxItem == \"string\" ? ctxItem : \"$documentFragment\",\n\t\t*getAttributeKeys() {},\n\t\tgetAttribute() {}\n\t};\n\telse return {\n\t\tname: ctxItem.is(\"element\") ? ctxItem.name : \"$text\",\n\t\t*getAttributeKeys() {\n\t\t\tyield* ctxItem.getAttributeKeys();\n\t\t},\n\t\tgetAttribute(key) {\n\t\t\treturn ctxItem.getAttribute(key);\n\t\t}\n\t};\n}\n/**\n* Generator function returning values from provided walkers, switching between them at each iteration. If only one walker\n* is provided it will return data only from that walker.\n*\n* @param backward Walker iterating in backward direction.\n* @param forward Walker iterating in forward direction.\n* @returns Object returned at each iteration contains `value` and `walker` (informing which walker returned\n* given value) fields.\n*/\nfunction* combineWalkers(backward, forward) {\n\tlet done = false;\n\twhile (!done) {\n\t\tdone = true;\n\t\tif (backward) {\n\t\t\tconst step = backward.next();\n\t\t\tif (!step.done) {\n\t\t\t\tdone = false;\n\t\t\t\tyield {\n\t\t\t\t\twalker: backward,\n\t\t\t\t\tvalue: step.value\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (forward) {\n\t\t\tconst step = forward.next();\n\t\t\tif (!step.done) {\n\t\t\t\tdone = false;\n\t\t\t\tyield {\n\t\t\t\t\twalker: forward,\n\t\t\t\t\tvalue: step.value\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n/**\n* Takes an array of non-intersecting ranges. For each of them gets minimal flat ranges covering that range and returns\n* all those minimal flat ranges.\n*\n* @param ranges Ranges to process.\n* @returns Minimal flat ranges of given `ranges`.\n*/\nfunction* convertToMinimalFlatRanges(ranges) {\n\tfor (const range of ranges) yield* range.getMinimalFlatRanges();\n}\nfunction removeDisallowedAttributeFromNode(schema, node, writer) {\n\tfor (const attribute of node.getAttributeKeys()) if (!schema.checkAttribute(node, attribute)) writer.removeAttribute(attribute, node);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/conversion/upcastdispatcher\n*/\nconst UpcastDispatcherBase = /* #__PURE__ */ EmitterMixin();\n/**\n* Upcast dispatcher is a central point of the view-to-model conversion, which is a process of\n* converting a given {@link module:engine/view/documentfragment~ViewDocumentFragment view document fragment} or\n* {@link module:engine/view/element~ViewElement view element} into a correct model structure.\n*\n* During the conversion process, the dispatcher fires events for all {@link module:engine/view/node~ViewNode view nodes}\n* from the converted view document fragment.\n* Special callbacks called \"converters\" should listen to these events in order to convert the view nodes.\n*\n* The second parameter of the callback is the `data` object with the following properties:\n*\n* * `data.viewItem` contains a {@link module:engine/view/node~ViewNode view node} or a\n* {@link module:engine/view/documentfragment~ViewDocumentFragment view document fragment}\n* that is converted at the moment and might be handled by the callback.\n* * `data.modelRange` is used to point to the result\n* of the current conversion (e.g. the element that is being inserted)\n* and is always a {@link module:engine/model/range~ModelRange} when the conversion succeeds.\n* * `data.modelCursor` is a {@link module:engine/model/position~ModelPosition position} on which the converter should insert\n* the newly created items.\n*\n* The third parameter of the callback is an instance of {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi}\n* which provides additional tools for converters.\n*\n* You can read more about conversion in the {@glink framework/deep-dive/conversion/upcast Upcast conversion} guide.\n*\n* Examples of event-based converters:\n*\n* ```ts\n* // A converter for links (<a>).\n* editor.data.upcastDispatcher.on( 'element:a', ( evt, data, conversionApi ) => {\n* \tif ( conversionApi.consumable.consume( data.viewItem, { name: true, attributes: [ 'href' ] } ) ) {\n* \t\t// The <a> element is inline and is represented by an attribute in the model.\n* \t\t// This is why you need to convert only children.\n* \t\tconst { modelRange } = conversionApi.convertChildren( data.viewItem, data.modelCursor );\n*\n* \t\tfor ( let item of modelRange.getItems() ) {\n* \t\t\tif ( conversionApi.schema.checkAttribute( item, 'linkHref' ) ) {\n* \t\t\t\tconversionApi.writer.setAttribute( 'linkHref', data.viewItem.getAttribute( 'href' ), item );\n* \t\t\t}\n* \t\t}\n* \t}\n* } );\n*\n* // Convert <p> element's font-size style.\n* // Note: You should use a low-priority observer in order to ensure that\n* // it is executed after the element-to-element converter.\n* editor.data.upcastDispatcher.on( 'element:p', ( evt, data, conversionApi ) => {\n* \tconst { consumable, schema, writer } = conversionApi;\n*\n* \tif ( !consumable.consume( data.viewItem, { style: 'font-size' } ) ) {\n* \t\treturn;\n* \t}\n*\n* \tconst fontSize = data.viewItem.getStyle( 'font-size' );\n*\n* \t// Do not go for the model element after data.modelCursor because it might happen\n* \t// that a single view element was converted to multiple model elements. Get all of them.\n* \tfor ( const item of data.modelRange.getItems( { shallow: true } ) ) {\n* \t\tif ( schema.checkAttribute( item, 'fontSize' ) ) {\n* \t\t\twriter.setAttribute( 'fontSize', fontSize, item );\n* \t\t}\n* \t}\n* }, { priority: 'low' } );\n*\n* // Convert all elements which have no custom converter into a paragraph (autoparagraphing).\n* editor.data.upcastDispatcher.on( 'element', ( evt, data, conversionApi ) => {\n* \t// Check if an element can be converted.\n* \tif ( !conversionApi.consumable.test( data.viewItem, { name: data.viewItem.name } ) ) {\n* \t\t// When an element is already consumed by higher priority converters, do nothing.\n* \t\treturn;\n* \t}\n*\n* \tconst paragraph = conversionApi.writer.createElement( 'paragraph' );\n*\n* \t// Try to safely insert a paragraph at the model cursor - it will find an allowed parent for the current element.\n* \tif ( !conversionApi.safeInsert( paragraph, data.modelCursor ) ) {\n* \t\t// When an element was not inserted, it means that you cannot insert a paragraph at this position.\n* \t\treturn;\n* \t}\n*\n* \t// Consume the inserted element.\n* \tconversionApi.consumable.consume( data.viewItem, { name: data.viewItem.name } ) );\n*\n* \t// Convert the children to a paragraph.\n* \tconst { modelRange } = conversionApi.convertChildren( data.viewItem, paragraph ) );\n*\n* \t// Update `modelRange` and `modelCursor` in the `data` as a conversion result.\n* \tconversionApi.updateConversionResult( paragraph, data );\n* }, { priority: 'low' } );\n* ```\n*\n* @fires viewCleanup\n* @fires element\n* @fires text\n* @fires documentFragment\n*/\nvar UpcastDispatcher = class extends UpcastDispatcherBase {\n\t/**\n\t* An interface passed by the dispatcher to the event callbacks.\n\t*/\n\tconversionApi;\n\t/**\n\t* The list of elements that were created during splitting.\n\t*\n\t* After the conversion process, the list is cleared.\n\t*/\n\t_splitParts = /* @__PURE__ */ new Map();\n\t/**\n\t* The list of cursor parent elements that were created during splitting.\n\t*\n\t* After the conversion process the list is cleared.\n\t*/\n\t_cursorParents = /* @__PURE__ */ new Map();\n\t/**\n\t* The position in the temporary structure where the converted content is inserted. The structure reflects the context of\n\t* the target position where the content will be inserted. This property is built based on the context parameter of the\n\t* convert method.\n\t*/\n\t_modelCursor = null;\n\t/**\n\t* The list of elements that were created during the splitting but should not get removed on conversion end even if they are empty.\n\t*\n\t* The list is cleared after the conversion process.\n\t*/\n\t_emptyElementsToKeep = /* @__PURE__ */ new Set();\n\t/**\n\t* Creates an upcast dispatcher that operates using the passed API.\n\t*\n\t* @see module:engine/conversion/upcastdispatcher~UpcastConversionApi\n\t* @param conversionApi Additional properties for an interface that will be passed to events fired\n\t* by the upcast dispatcher.\n\t*/\n\tconstructor(conversionApi) {\n\t\tsuper();\n\t\tthis.conversionApi = {\n\t\t\t...conversionApi,\n\t\t\tconsumable: null,\n\t\t\twriter: null,\n\t\t\tstore: null,\n\t\t\tconvertItem: (viewItem, modelCursor) => this._convertItem(viewItem, modelCursor),\n\t\t\tconvertChildren: (viewElement, positionOrElement) => this._convertChildren(viewElement, positionOrElement),\n\t\t\tsafeInsert: (modelNode, position) => this._safeInsert(modelNode, position),\n\t\t\tupdateConversionResult: (modelElement, data) => this._updateConversionResult(modelElement, data),\n\t\t\tsplitToAllowedParent: (modelNode, modelCursor) => this._splitToAllowedParent(modelNode, modelCursor),\n\t\t\tgetSplitParts: (modelElement) => this._getSplitParts(modelElement),\n\t\t\tkeepEmptyElement: (modelElement) => this._keepEmptyElement(modelElement)\n\t\t};\n\t}\n\t/**\n\t* Starts the conversion process. The entry point for the conversion.\n\t*\n\t* **Note:** The default `context` value is `[ '$root' ]`, which only matches the generic root. When the editor uses\n\t* a custom root {@link module:core/editor/editorconfig~RootConfig#modelElement `modelElement`}, pass the target\n\t* {@link module:engine/model/rootelement~ModelRootElement root element} (or its configured model element name)\n\t* explicitly, otherwise the conversion result may be wrong.\n\t* See the {@glink framework/deep-dive/schema#custom-root-elements Custom root elements} section of the\n\t* {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*\n\t* @fires element\n\t* @fires text\n\t* @fires documentFragment\n\t* @param viewElement The part of the view to be converted.\n\t* @param writer An instance of the model writer.\n\t* @param context Elements will be converted according to this context.\n\t* @returns Model data that is the result of the conversion process\n\t* wrapped in `DocumentFragment`. Converted marker elements will be set as the document fragment's\n\t* {@link module:engine/model/documentfragment~ModelDocumentFragment#markers static markers map}.\n\t*/\n\tconvert(viewElement, writer, context = [\"$root\"]) {\n\t\tthis.fire(\"viewCleanup\", viewElement);\n\t\tthis._modelCursor = createContextTree(context, writer);\n\t\tthis.conversionApi.writer = writer;\n\t\tthis.conversionApi.consumable = ViewConsumable.createFrom(viewElement);\n\t\tthis.conversionApi.store = {};\n\t\tconst { modelRange } = this._convertItem(viewElement, this._modelCursor);\n\t\tconst documentFragment = writer.createDocumentFragment();\n\t\tif (modelRange) {\n\t\t\tthis._removeEmptyElements();\n\t\t\tconst parent = this._modelCursor.parent;\n\t\t\tconst children = parent._removeChildren(0, parent.childCount);\n\t\t\tdocumentFragment._insertChild(0, children);\n\t\t\tdocumentFragment.markers = extractMarkersFromModelFragment(documentFragment, writer);\n\t\t}\n\t\tthis._modelCursor = null;\n\t\tthis._splitParts.clear();\n\t\tthis._cursorParents.clear();\n\t\tthis._emptyElementsToKeep.clear();\n\t\tthis.conversionApi.writer = null;\n\t\tthis.conversionApi.store = null;\n\t\treturn documentFragment;\n\t}\n\t/**\n\t* @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#convertItem\n\t*/\n\t_convertItem(viewItem, modelCursor) {\n\t\tconst data = {\n\t\t\tviewItem,\n\t\t\tmodelCursor,\n\t\t\tmodelRange: null\n\t\t};\n\t\tif (viewItem.is(\"element\")) this.fire(`element:${viewItem.name}`, data, this.conversionApi);\n\t\telse if (viewItem.is(\"$text\")) this.fire(\"text\", data, this.conversionApi);\n\t\telse this.fire(\"documentFragment\", data, this.conversionApi);\n\t\tif (data.modelRange && !(data.modelRange instanceof ModelRange))\n /**\n\t\t* Incorrect conversion result was dropped.\n\t\t*\n\t\t* {@link module:engine/model/range~ModelRange Model range} should be a conversion result.\n\t\t*\n\t\t* @error view-conversion-dispatcher-incorrect-result\n\t\t*/\n\t\tthrow new CKEditorError(\"view-conversion-dispatcher-incorrect-result\", this);\n\t\treturn {\n\t\t\tmodelRange: data.modelRange,\n\t\t\tmodelCursor: data.modelCursor\n\t\t};\n\t}\n\t/**\n\t* @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#convertChildren\n\t*/\n\t_convertChildren(viewItem, elementOrModelCursor) {\n\t\tlet nextModelCursor = elementOrModelCursor.is(\"position\") ? elementOrModelCursor : ModelPosition._createAt(elementOrModelCursor, 0);\n\t\tconst modelRange = new ModelRange(nextModelCursor);\n\t\tfor (const viewChild of Array.from(viewItem.getChildren())) {\n\t\t\tconst result = this._convertItem(viewChild, nextModelCursor);\n\t\t\tif (result.modelRange instanceof ModelRange) {\n\t\t\t\tmodelRange.end = result.modelRange.end;\n\t\t\t\tnextModelCursor = result.modelCursor;\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tmodelRange,\n\t\t\tmodelCursor: nextModelCursor\n\t\t};\n\t}\n\t/**\n\t* @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#safeInsert\n\t*/\n\t_safeInsert(modelNode, position) {\n\t\tconst splitResult = this._splitToAllowedParent(modelNode, position);\n\t\tif (!splitResult) return false;\n\t\tthis.conversionApi.writer.insert(modelNode, splitResult.position);\n\t\treturn true;\n\t}\n\t/**\n\t* @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#updateConversionResult\n\t*/\n\t_updateConversionResult(modelElement, data) {\n\t\tconst parts = this._getSplitParts(modelElement);\n\t\tconst writer = this.conversionApi.writer;\n\t\tif (!data.modelRange) data.modelRange = writer.createRange(writer.createPositionBefore(modelElement), writer.createPositionAfter(parts[parts.length - 1]));\n\t\tconst savedCursorParent = this._cursorParents.get(modelElement);\n\t\tif (savedCursorParent) data.modelCursor = writer.createPositionAt(savedCursorParent, 0);\n\t\telse data.modelCursor = data.modelRange.end;\n\t}\n\t/**\n\t* @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#splitToAllowedParent\n\t*/\n\t_splitToAllowedParent(node, modelCursor) {\n\t\tconst { schema, writer } = this.conversionApi;\n\t\tlet allowedParent = schema.findAllowedParent(modelCursor, node);\n\t\tif (allowedParent) {\n\t\t\tif (allowedParent === modelCursor.parent) return { position: modelCursor };\n\t\t\tif (this._modelCursor.parent.getAncestors().includes(allowedParent)) allowedParent = null;\n\t\t}\n\t\tif (!allowedParent) {\n\t\t\tif (!isParagraphable(modelCursor, node, schema)) return null;\n\t\t\treturn { position: wrapInParagraph(modelCursor, writer) };\n\t\t}\n\t\tconst splitResult = this.conversionApi.writer.split(modelCursor, allowedParent);\n\t\tconst stack = [];\n\t\tfor (const treeWalkerValue of splitResult.range.getWalker()) if (treeWalkerValue.type == \"elementEnd\") stack.push(treeWalkerValue.item);\n\t\telse {\n\t\t\tconst originalPart = stack.pop();\n\t\t\tconst splitPart = treeWalkerValue.item;\n\t\t\tthis._registerSplitPair(originalPart, splitPart);\n\t\t}\n\t\tconst cursorParent = splitResult.range.end.parent;\n\t\tthis._cursorParents.set(node, cursorParent);\n\t\treturn {\n\t\t\tposition: splitResult.position,\n\t\t\tcursorParent\n\t\t};\n\t}\n\t/**\n\t* Registers that a `splitPart` element is a split part of the `originalPart` element.\n\t*\n\t* The data set by this method is used by {@link #_getSplitParts} and {@link #_removeEmptyElements}.\n\t*/\n\t_registerSplitPair(originalPart, splitPart) {\n\t\tif (!this._splitParts.has(originalPart)) this._splitParts.set(originalPart, [originalPart]);\n\t\tconst list = this._splitParts.get(originalPart);\n\t\tthis._splitParts.set(splitPart, list);\n\t\tlist.push(splitPart);\n\t}\n\t/**\n\t* @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#getSplitParts\n\t*/\n\t_getSplitParts(element) {\n\t\tlet parts;\n\t\tif (!this._splitParts.has(element)) parts = [element];\n\t\telse parts = this._splitParts.get(element);\n\t\treturn parts;\n\t}\n\t/**\n\t* Mark an element that were created during the splitting to not get removed on conversion end even if it is empty.\n\t*/\n\t_keepEmptyElement(element) {\n\t\tthis._emptyElementsToKeep.add(element);\n\t}\n\t/**\n\t* Checks if there are any empty elements created while splitting and removes them.\n\t*\n\t* This method works recursively to re-check empty elements again after at least one element was removed in the initial call,\n\t* as some elements might have become empty after other empty elements were removed from them.\n\t*/\n\t_removeEmptyElements() {\n\t\tconst toRemove = /* @__PURE__ */ new Map();\n\t\tfor (const element of this._splitParts.keys()) if (element.isEmpty && !this._emptyElementsToKeep.has(element)) {\n\t\t\tconst children = toRemove.get(element.parent) || [];\n\t\t\tchildren.push(element);\n\t\t\tthis._splitParts.delete(element);\n\t\t\ttoRemove.set(element.parent, children);\n\t\t}\n\t\tfor (const [parent, children] of toRemove) parent._removeChildrenArray(children);\n\t\tif (toRemove.size) this._removeEmptyElements();\n\t}\n};\n/**\n* Traverses given model item and searches elements which marks marker range. Found element is removed from\n* ModelDocumentFragment but path of this element is stored in a Map which is then returned.\n*\n* @param modelItem Fragment of model.\n* @returns List of static markers.\n*/\nfunction extractMarkersFromModelFragment(modelItem, writer) {\n\tconst markerElements = /* @__PURE__ */ new Set();\n\tconst markers = /* @__PURE__ */ new Map();\n\tconst range = ModelRange._createIn(modelItem).getItems();\n\tfor (const item of range) if (item.is(\"element\", \"$marker\")) markerElements.add(item);\n\tfor (const markerElement of markerElements) {\n\t\tconst markerName = markerElement.getAttribute(\"data-name\");\n\t\tconst currentPosition = writer.createPositionBefore(markerElement);\n\t\tif (!markers.has(markerName)) markers.set(markerName, new ModelRange(currentPosition.clone()));\n\t\telse markers.get(markerName).end = currentPosition.clone();\n\t\twriter.remove(markerElement);\n\t}\n\treturn markers;\n}\n/**\n* Creates model fragment according to given context and returns position in the bottom (the deepest) element.\n*/\nfunction createContextTree(contextDefinition, writer) {\n\tlet position;\n\tfor (const item of new ModelSchemaContext(contextDefinition)) {\n\t\tconst attributes = {};\n\t\tfor (const key of item.getAttributeKeys()) attributes[key] = item.getAttribute(key);\n\t\tconst current = writer.createElement(item.name, attributes);\n\t\tif (position) writer.insert(current, position);\n\t\tposition = ModelPosition._createAt(current, 0);\n\t}\n\treturn position;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Basic HTML writer. It uses the native `innerHTML` property for basic conversion\n* from a document fragment to an HTML string.\n*\n* @internal\n*/\nvar BasicHtmlWriter = class {\n\t/**\n\t* Returns an HTML string created from the document fragment.\n\t*/\n\tgetHtml(fragment) {\n\t\tconst container = global.document.implementation.createHTMLDocument(\"\").createElement(\"div\");\n\t\tcontainer.appendChild(fragment);\n\t\treturn container.innerHTML;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/dataprocessor/htmldataprocessor\n*/\n/**\n* The HTML data processor class.\n* This data processor implementation uses HTML as input and output data.\n*/\nvar HtmlDataProcessor = class {\n\t/**\n\t* A DOM parser instance used to parse an HTML string to an HTML document.\n\t*/\n\tdomParser;\n\t/**\n\t* A DOM converter used to convert DOM elements to view elements.\n\t*/\n\tdomConverter;\n\t/**\n\t* A basic HTML writer instance used to convert DOM elements to an HTML string.\n\t*/\n\thtmlWriter;\n\tskipComments = true;\n\t/**\n\t* Creates a new instance of the HTML data processor class.\n\t*\n\t* @param document The view document instance.\n\t*/\n\tconstructor(document) {\n\t\tthis.domParser = new DOMParser();\n\t\tthis.domConverter = new ViewDomConverter(document, { renderingMode: \"data\" });\n\t\tthis.htmlWriter = new BasicHtmlWriter();\n\t}\n\t/**\n\t* Converts a provided {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment}\n\t* to data format &ndash; in this case to an HTML string.\n\t*\n\t* @returns HTML string.\n\t*/\n\ttoData(viewFragment) {\n\t\tconst domFragment = this.domConverter.viewToDom(viewFragment);\n\t\treturn this.htmlWriter.getHtml(domFragment);\n\t}\n\t/**\n\t* Converts the provided HTML string to a view tree.\n\t*\n\t* @param data An HTML string.\n\t* @returns A converted view element.\n\t*/\n\ttoView(data) {\n\t\tconst domFragment = this._toDom(data);\n\t\treturn this.domConverter.domToView(domFragment, { skipComments: this.skipComments });\n\t}\n\t/**\n\t* Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t* and not processed during the conversion from the DOM to the view elements.\n\t*\n\t* The raw data can be later accessed by a\n\t* {@link module:engine/view/element~ViewElement#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t*\n\t* @param pattern Pattern matching all view elements whose content should be treated as raw data.\n\t*/\n\tregisterRawContentMatcher(pattern) {\n\t\tthis.domConverter.registerRawContentMatcher(pattern);\n\t}\n\t/**\n\t* If the processor is set to use marked fillers, it will insert `&nbsp;` fillers wrapped in `<span>` elements\n\t* (`<span data-cke-filler=\"true\">&nbsp;</span>`) instead of regular `&nbsp;` characters.\n\t*\n\t* This mode allows for a more precise handling of the block fillers (so they do not leak into the editor content) but\n\t* bloats the editor data with additional markup.\n\t*\n\t* This mode may be required by some features and will be turned on by them automatically.\n\t*\n\t* @param type Whether to use the default or the marked `&nbsp;` block fillers.\n\t*/\n\tuseFillerType(type) {\n\t\tthis.domConverter.blockFillerMode = type == \"marked\" ? \"markedNbsp\" : \"nbsp\";\n\t}\n\t/**\n\t* Converts an HTML string to its DOM representation. Returns a document fragment containing nodes parsed from\n\t* the provided data.\n\t*/\n\t_toDom(data) {\n\t\tif (!/<(?:html|body|head|meta)(?:\\s[^>]*)?>/i.test(data.trim().slice(0, 1e4))) data = `<body>${data}</body>`;\n\t\tconst document = this.domParser.parseFromString(data, \"text/html\");\n\t\tconst fragment = document.createDocumentFragment();\n\t\tconst bodyChildNodes = document.body.childNodes;\n\t\twhile (bodyChildNodes.length > 0) fragment.appendChild(bodyChildNodes[0]);\n\t\treturn fragment;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/controller/datacontroller\n*/\nconst DataControllerBase = /* #__PURE__ */ EmitterMixin();\n/**\n* Controller for the data pipeline. The data pipeline controls how data is retrieved from the document\n* and set inside it. Hence, the controller features two methods which allow to {@link ~DataController#get get}\n* and {@link ~DataController#set set} data of the {@link ~DataController#model model}\n* using the given:\n*\n* * {@link module:engine/dataprocessor/dataprocessor~DataProcessor data processor},\n* * downcast converters,\n* * upcast converters.\n*\n* An instance of the data controller is always available in the {@link module:core/editor/editor~Editor#data `editor.data`}\n* property:\n*\n* ```ts\n* editor.data.get( { rootName: 'customRoot' } ); // -> '<p>Hello!</p>'\n* ```\n*/\nvar DataController = class extends DataControllerBase {\n\t/**\n\t* Data model.\n\t*/\n\tmodel;\n\t/**\n\t* Mapper used for the conversion. It has no permanent bindings, because these are created while getting data and\n\t* are cleared directly after the data are converted. However, the mapper is defined as a class property, because\n\t* it needs to be passed to the `DowncastDispatcher` as a conversion API.\n\t*/\n\tmapper;\n\t/**\n\t* Downcast dispatcher used by the {@link #get get method}. Downcast converters should be attached to it.\n\t*/\n\tdowncastDispatcher;\n\t/**\n\t* Upcast dispatcher used by the {@link #set set method}. Upcast converters should be attached to it.\n\t*/\n\tupcastDispatcher;\n\t/**\n\t* The view document used by the data controller.\n\t*/\n\tviewDocument;\n\t/**\n\t* Styles processor used during the conversion.\n\t*/\n\tstylesProcessor;\n\t/**\n\t* Data processor used specifically for HTML conversion.\n\t*/\n\thtmlProcessor;\n\t/**\n\t* Data processor used during the conversion.\n\t* Same instance as {@link #htmlProcessor} by default. Can be replaced at run time to handle different format, e.g. XML or Markdown.\n\t*/\n\tprocessor;\n\t/**\n\t* The view downcast writer just for data conversion purposes, i.e. to modify\n\t* the {@link #viewDocument}.\n\t*/\n\t_viewWriter;\n\t/**\n\t* Creates a data controller instance.\n\t*\n\t* @param model Data model.\n\t* @param stylesProcessor The styles processor instance.\n\t*/\n\tconstructor(model, stylesProcessor) {\n\t\tsuper();\n\t\tthis.model = model;\n\t\tthis.mapper = new Mapper();\n\t\tthis.downcastDispatcher = new DowncastDispatcher({\n\t\t\tmapper: this.mapper,\n\t\t\tschema: model.schema\n\t\t});\n\t\tthis.downcastDispatcher.on(\"insert:$text\", insertText(), { priority: \"lowest\" });\n\t\tthis.downcastDispatcher.on(\"insert\", insertAttributesAndChildren(), { priority: \"lowest\" });\n\t\tthis.upcastDispatcher = new UpcastDispatcher({ schema: model.schema });\n\t\tthis.viewDocument = new ViewDocument(stylesProcessor);\n\t\tthis.stylesProcessor = stylesProcessor;\n\t\tthis.htmlProcessor = new HtmlDataProcessor(this.viewDocument);\n\t\tthis.processor = this.htmlProcessor;\n\t\tthis._viewWriter = new ViewDowncastWriter(this.viewDocument);\n\t\tthis.upcastDispatcher.on(\"text\", convertText(), { priority: \"lowest\" });\n\t\tthis.upcastDispatcher.on(\"element\", convertToModelFragment(), { priority: \"lowest\" });\n\t\tthis.upcastDispatcher.on(\"documentFragment\", convertToModelFragment(), { priority: \"lowest\" });\n\t\tObservableMixin().prototype.decorate.call(this, \"init\");\n\t\tObservableMixin().prototype.decorate.call(this, \"set\");\n\t\tObservableMixin().prototype.decorate.call(this, \"get\");\n\t\tObservableMixin().prototype.decorate.call(this, \"toView\");\n\t\tObservableMixin().prototype.decorate.call(this, \"toModel\");\n\t\tthis.on(\"init\", () => {\n\t\t\tthis.fire(\"ready\");\n\t\t}, { priority: \"lowest\" });\n\t\tthis.on(\"ready\", () => {\n\t\t\tthis.model.enqueueChange({ isUndoable: false }, autoParagraphEmptyRoots);\n\t\t}, { priority: \"lowest\" });\n\t}\n\t/**\n\t* Returns the model's data converted by downcast dispatchers attached to {@link #downcastDispatcher} and\n\t* formatted by the {@link #processor data processor}.\n\t*\n\t* A warning is logged when you try to retrieve data for a detached root, as most probably this is a mistake. A detached root should\n\t* be treated like it is removed, and you should not save its data. Note, that the detached root data is always an empty string.\n\t*\n\t* @fires get\n\t* @param options Additional configuration for the retrieved data. `DataController` provides two optional\n\t* properties: `rootName` and `trim`. Other properties of this object are specified by various editor features.\n\t* @param options.rootName Root name. Default 'main'.\n\t* @param options.trim Whether returned data should be trimmed. This option is set to `empty` by default,\n\t* which means whenever editor content is considered empty, an empty string will be returned. To turn off trimming completely\n\t* use `'none'`. In such cases the exact content will be returned (for example a `<p>&nbsp;</p>` for an empty editor).\n\t* @returns Output data.\n\t*/\n\tget(options = {}) {\n\t\tconst { rootName = \"main\", trim = \"empty\" } = options;\n\t\tif (!this._checkIfRootsExists([rootName]))\n /**\n\t\t* Cannot get data from a non-existing root. This error is thrown when\n\t\t* {@link module:engine/controller/datacontroller~DataController#get `DataController#get()` method}\n\t\t* is called with a non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t* calling {@link module:engine/controller/datacontroller~DataController#get} like:\n\t\t*\n\t\t* ```ts\n\t\t* data.get( { rootName: 'root2' } );\n\t\t* ```\n\t\t*\n\t\t* will throw this error.\n\t\t*\n\t\t* @error datacontroller-get-non-existent-root\n\t\t*/\n\t\tthrow new CKEditorError(\"datacontroller-get-non-existent-root\", this);\n\t\tconst root = this.model.document.getRoot(rootName);\n\t\tif (!root.isAttached())\n /**\n\t\t* Retrieving document data for a detached root.\n\t\t*\n\t\t* This usually indicates an error as a detached root should be considered \"removed\" and should not be included in the\n\t\t* document data.\n\t\t*\n\t\t* @error datacontroller-get-detached-root\n\t\t*/\n\t\tlogWarning(\"datacontroller-get-detached-root\", this);\n\t\tif (trim === \"empty\" && !this.model.hasContent(root, { ignoreWhitespaces: true })) return \"\";\n\t\treturn this.stringify(root, options);\n\t}\n\t/**\n\t* Returns the content of the given {@link module:engine/model/element~ModelElement model's element} or\n\t* {@link module:engine/model/documentfragment~ModelDocumentFragment model document fragment} converted by the downcast converters\n\t* attached to the {@link #downcastDispatcher} and formatted by the {@link #processor data processor}.\n\t*\n\t* @param modelElementOrFragment The element whose content will be stringified.\n\t* @param options Additional configuration passed to the conversion process.\n\t* @returns Output data.\n\t*/\n\tstringify(modelElementOrFragment, options = {}) {\n\t\tconst viewDocumentFragment = this.toView(modelElementOrFragment, options);\n\t\treturn this.processor.toData(viewDocumentFragment);\n\t}\n\t/**\n\t* Returns the content of the given {@link module:engine/model/element~ModelElement model element} or\n\t* {@link module:engine/model/documentfragment~ModelDocumentFragment model document fragment} converted by the downcast\n\t* converters attached to {@link #downcastDispatcher} into a\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment view document fragment}.\n\t*\n\t* @fires toView\n\t* @param modelElementOrFragment Element or document fragment whose content will be converted.\n\t* @param options Additional configuration that will be available through the\n\t* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi#options} during the conversion process.\n\t* @returns Output view ModelDocumentFragment.\n\t*/\n\ttoView(modelElementOrFragment, options = {}) {\n\t\tconst viewDocument = this.viewDocument;\n\t\tconst viewWriter = this._viewWriter;\n\t\tthis.mapper.clearBindings();\n\t\tconst modelRange = ModelRange._createIn(modelElementOrFragment);\n\t\tconst viewDocumentFragment = new ViewDocumentFragment(viewDocument);\n\t\tthis.mapper.bindElements(modelElementOrFragment, viewDocumentFragment);\n\t\tconst markers = modelElementOrFragment.is(\"documentFragment\") ? modelElementOrFragment.markers : _getMarkersRelativeToElement(modelElementOrFragment);\n\t\tthis.downcastDispatcher.convert(modelRange, markers, viewWriter, options);\n\t\treturn viewDocumentFragment;\n\t}\n\t/**\n\t* Sets the initial input data parsed by the {@link #processor data processor} and\n\t* converted by the {@link #upcastDispatcher view-to-model converters}.\n\t* Initial data can be only set to a document whose {@link module:engine/model/document~ModelDocument#version} is equal 0.\n\t*\n\t* **Note** This method is {@link module:utils/observablemixin~Observable#decorate decorated} which is\n\t* used by e.g. collaborative editing plugin that syncs remote data on init.\n\t*\n\t* When data is passed as a string, it is initialized on the default `main` root:\n\t*\n\t* ```ts\n\t* dataController.init( '<p>Foo</p>' ); // Initializes data on the `main` root only, as no other is specified.\n\t* ```\n\t*\n\t* To initialize data on a different root or multiple roots at once, an object containing `rootName` - `data` pairs should be passed:\n\t*\n\t* ```ts\n\t* dataController.init( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Initializes data on both the `main` and `title` roots.\n\t* ```\n\t*\n\t* @fires init\n\t* @param data Input data as a string or an object containing the `rootName` - `data`\n\t* pairs to initialize data on multiple roots at once.\n\t* @returns Promise that is resolved after the data is set on the editor.\n\t*/\n\tinit(data) {\n\t\tif (this.model.document.version)\n /**\n\t\t* Cannot set initial data to a non-empty {@link module:engine/model/document~ModelDocument}.\n\t\t* Initial data should be set once, during the {@link module:core/editor/editor~Editor} initialization,\n\t\t* when the {@link module:engine/model/document~ModelDocument#version} is equal 0.\n\t\t*\n\t\t* @error datacontroller-init-document-not-empty\n\t\t*/\n\t\tthrow new CKEditorError(\"datacontroller-init-document-not-empty\", this);\n\t\tlet initialData = {};\n\t\tif (typeof data === \"string\") initialData.main = data;\n\t\telse initialData = data;\n\t\tif (!this._checkIfRootsExists(Object.keys(initialData)))\n /**\n\t\t* Cannot init data on a non-existent root. This error is thrown when\n\t\t* {@link module:engine/controller/datacontroller~DataController#init DataController#init() method}\n\t\t* is called with non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t* calling {@link module:engine/controller/datacontroller~DataController#init} like:\n\t\t*\n\t\t* ```ts\n\t\t* data.init( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );\n\t\t* ```\n\t\t*\n\t\t* will throw this error.\n\t\t*\n\t\t* @error datacontroller-init-non-existent-root\n\t\t*/\n\t\tthrow new CKEditorError(\"datacontroller-init-non-existent-root\", this);\n\t\tthis.model.enqueueChange({ isUndoable: false }, (writer) => {\n\t\t\tfor (const rootName of Object.keys(initialData)) {\n\t\t\t\tconst modelRoot = this.model.document.getRoot(rootName);\n\t\t\t\twriter.insert(this.parse(initialData[rootName], modelRoot), modelRoot, 0);\n\t\t\t}\n\t\t});\n\t\treturn Promise.resolve();\n\t}\n\t/**\n\t* Sets the input data parsed by the {@link #processor data processor} and\n\t* converted by the {@link #upcastDispatcher view-to-model converters}.\n\t* This method can be used any time to replace existing editor data with the new one without clearing the\n\t* {@link module:engine/model/document~ModelDocument#history document history}.\n\t*\n\t* This method also creates a batch with all the changes applied. If all you need is to parse data, use\n\t* the {@link #parse} method.\n\t*\n\t* When data is passed as a string it is set on the default `main` root:\n\t*\n\t* ```ts\n\t* dataController.set( '<p>Foo</p>' ); // Sets data on the `main` root, as no other is specified.\n\t* ```\n\t*\n\t* To set data on a different root or multiple roots at once, an object containing `rootName` - `data` pairs should be passed:\n\t*\n\t* ```ts\n\t* dataController.set( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Sets data on the `main` and `title` roots as specified.\n\t* ```\n\t*\n\t* To set the data with a preserved undo stack and add the change to the undo stack, set `{ isUndoable: true }` as a `batchType` option.\n\t*\n\t* ```ts\n\t* dataController.set( '<p>Foo</p>', { batchType: { isUndoable: true } } );\n\t* ```\n\t*\n\t* @fires set\n\t* @param data Input data as a string or an object containing the `rootName` - `data`\n\t* pairs to set data on multiple roots at once.\n\t* @param options Options for setting data.\n\t* @param options.batchType The batch type that will be used to create a batch for the changes applied by this method.\n\t* By default, the batch will be set as {@link module:engine/model/batch~Batch#isUndoable not undoable} and the undo stack will be\n\t* cleared after the new data is applied (all undo steps will be removed). If the batch type `isUndoable` flag is be set to `true`,\n\t* the undo stack will be preserved instead and not cleared when new data is applied.\n\t*/\n\tset(data, options = {}) {\n\t\tlet newData = {};\n\t\tif (typeof data === \"string\") newData.main = data;\n\t\telse newData = data;\n\t\tif (!this._checkIfRootsExists(Object.keys(newData)))\n /**\n\t\t* Cannot set data on a non-existent root. This error is thrown when the\n\t\t* {@link module:engine/controller/datacontroller~DataController#set DataController#set() method}\n\t\t* is called with non-existent root name. For example, if there is an editor instance with only the default `main` root,\n\t\t* calling {@link module:engine/controller/datacontroller~DataController#set} like:\n\t\t*\n\t\t* ```ts\n\t\t* data.set( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );\n\t\t* ```\n\t\t*\n\t\t* will throw this error.\n\t\t*\n\t\t* @error datacontroller-set-non-existent-root\n\t\t*/\n\t\tthrow new CKEditorError(\"datacontroller-set-non-existent-root\", this);\n\t\tthis.model.enqueueChange(options.batchType || {}, (writer) => {\n\t\t\twriter.setSelection(null);\n\t\t\twriter.removeSelectionAttribute(this.model.document.selection.getAttributeKeys());\n\t\t\tfor (const rootName of Object.keys(newData)) {\n\t\t\t\tconst modelRoot = this.model.document.getRoot(rootName);\n\t\t\t\twriter.remove(writer.createRangeIn(modelRoot));\n\t\t\t\twriter.insert(this.parse(newData[rootName], modelRoot), modelRoot, 0);\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* Returns the data parsed by the {@link #processor data processor} and then converted by upcast converters\n\t* attached to the {@link #upcastDispatcher}.\n\t*\n\t* **Note:** The default `context` value is `'$root'`, which only matches the generic root. When the editor uses a\n\t* custom root {@link module:core/editor/editorconfig~RootConfig#modelElement `modelElement`}, pass the target\n\t* {@link module:engine/model/rootelement~ModelRootElement root element} (or its configured model element name)\n\t* explicitly, otherwise the conversion result may be wrong.\n\t* See the {@glink framework/deep-dive/schema#custom-root-elements Custom root elements} section of the\n\t* {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*\n\t* @see #set\n\t* @param data Data to parse.\n\t* @param context Base context in which the view will be converted to the model.\n\t* See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t* @returns Parsed data.\n\t*/\n\tparse(data, context = \"$root\") {\n\t\tconst viewDocumentFragment = this.processor.toView(data);\n\t\treturn this.toModel(viewDocumentFragment, context);\n\t}\n\t/**\n\t* Returns the result of the given {@link module:engine/view/element~ViewElement view element} or\n\t* {@link module:engine/view/documentfragment~ViewDocumentFragment view document fragment} converted by the\n\t* {@link #upcastDispatcher view-to-model converters}, wrapped by {@link module:engine/model/documentfragment~ModelDocumentFragment}.\n\t*\n\t* When marker elements were converted during the conversion process, it will be set as a document fragment's\n\t* {@link module:engine/model/documentfragment~ModelDocumentFragment#markers static markers map}.\n\t*\n\t* **Note:** The default `context` value is `'$root'`, which only matches the generic root. When the editor uses a\n\t* custom root {@link module:core/editor/editorconfig~RootConfig#modelElement `modelElement`}, pass the target\n\t* {@link module:engine/model/rootelement~ModelRootElement root element} (or its configured model element name)\n\t* explicitly, otherwise the conversion result may be wrong.\n\t* See the {@glink framework/deep-dive/schema#custom-root-elements Custom root elements} section of the\n\t* {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*\n\t* @fires toModel\n\t* @param viewElementOrFragment The element or document fragment whose content will be converted.\n\t* @param context Base context in which the view will be converted to the model.\n\t* See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t* @returns Output document fragment.\n\t*/\n\ttoModel(viewElementOrFragment, context = \"$root\") {\n\t\treturn this.model.change((writer) => {\n\t\t\treturn this.upcastDispatcher.convert(viewElementOrFragment, writer, context);\n\t\t});\n\t}\n\t/**\n\t* Adds the style processor normalization rules.\n\t*\n\t* You can implement your own rules as well as use one of the available processor rules:\n\t*\n\t* * background: {@link module:engine/view/styles/background~addBackgroundStylesRules}\n\t* * border: {@link module:engine/view/styles/border~addBorderStylesRules}\n\t* * margin: {@link module:engine/view/styles/margin~addMarginStylesRules}\n\t* * padding: {@link module:engine/view/styles/padding~addPaddingStylesRules}\n\t*/\n\taddStyleProcessorRules(callback) {\n\t\tcallback(this.stylesProcessor);\n\t}\n\t/**\n\t* Registers a {@link module:engine/view/matcher~MatcherPattern} on an {@link #htmlProcessor htmlProcessor}\n\t* and a {@link #processor processor} for view elements whose content should be treated as raw data\n\t* and not processed during the conversion from DOM to view elements.\n\t*\n\t* The raw data can be later accessed by the\n\t* {@link module:engine/view/element~ViewElement#getCustomProperty view element custom property}\n\t* `\"$rawContent\"`.\n\t*\n\t* @param pattern Pattern matching all view elements whose content should be treated as a raw data.\n\t*/\n\tregisterRawContentMatcher(pattern) {\n\t\tif (this.processor && this.processor !== this.htmlProcessor) this.processor.registerRawContentMatcher(pattern);\n\t\tthis.htmlProcessor.registerRawContentMatcher(pattern);\n\t}\n\t/**\n\t* Removes all event listeners set by the DataController.\n\t*/\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Checks whether all provided root names are actually existing editor roots.\n\t*\n\t* @param rootNames Root names to check.\n\t* @returns Whether all provided root names are existing editor roots.\n\t*/\n\t_checkIfRootsExists(rootNames) {\n\t\tfor (const rootName of rootNames) if (!this.model.document.getRoot(rootName)) return false;\n\t\treturn true;\n\t}\n};\n/**\n* Helper function for downcast conversion.\n*\n* Takes a document element (element that is added to a model document) and checks which markers are inside it. If the marker is collapsed\n* at element boundary, it is considered as contained inside the element and marker range is returned. Otherwise, if the marker is\n* intersecting with the element, the intersection is returned.\n*/\nfunction _getMarkersRelativeToElement(element) {\n\tconst result = [];\n\tconst doc = element.root.document;\n\tif (!doc) return /* @__PURE__ */ new Map();\n\tconst elementRange = ModelRange._createIn(element);\n\tfor (const marker of doc.model.markers) {\n\t\tconst markerRange = marker.getRange();\n\t\tconst isMarkerCollapsed = markerRange.isCollapsed;\n\t\tconst isMarkerAtElementBoundary = markerRange.start.isEqual(elementRange.start) || markerRange.end.isEqual(elementRange.end);\n\t\tif (isMarkerCollapsed && isMarkerAtElementBoundary) result.push([marker.name, markerRange]);\n\t\telse {\n\t\t\tconst updatedMarkerRange = elementRange.getIntersection(markerRange);\n\t\t\tif (updatedMarkerRange) result.push([marker.name, updatedMarkerRange]);\n\t\t}\n\t}\n\treturn new Map(result);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/conversion/conversion\n*/\n/**\n* A utility class that helps add converters to upcast and downcast dispatchers.\n*\n* We recommend reading the {@glink framework/deep-dive/conversion/intro editor conversion} guide first to\n* understand the core concepts of the conversion mechanisms.\n*\n* An instance of the conversion manager is available in the\n* {@link module:core/editor/editor~Editor#conversion `editor.conversion`} property\n* and by default has the following groups of dispatchers (i.e. directions of conversion):\n*\n* * `downcast` (editing and data downcasts)\n* * `editingDowncast`\n* * `dataDowncast`\n* * `upcast`\n*\n* # One-way converters\n*\n* To add a converter to a specific group, use the {@link module:engine/conversion/conversion~Conversion#for `for()`}\n* method:\n*\n* ```ts\n* // Add a converter to editing downcast and data downcast.\n* editor.conversion.for( 'downcast' ).elementToElement( config ) );\n*\n* // Add a converter to the data pipepline only:\n* editor.conversion.for( 'dataDowncast' ).elementToElement( dataConversionConfig ) );\n*\n* // And a slightly different one for the editing pipeline:\n* editor.conversion.for( 'editingDowncast' ).elementToElement( editingConversionConfig ) );\n* ```\n*\n* See {@link module:engine/conversion/conversion~Conversion#for `for()`} method documentation to learn more about\n* available conversion helpers and how to use your custom ones.\n*\n* # Two-way converters\n*\n* Besides using one-way converters via the `for()` method, you can also use other methods available in this\n* class to add two-way converters (upcast and downcast):\n*\n* * {@link module:engine/conversion/conversion~Conversion#elementToElement `elementToElement()`} &ndash;\n* Model element to view element and vice versa.\n* * {@link module:engine/conversion/conversion~Conversion#attributeToElement `attributeToElement()`} &ndash;\n* Model attribute to view element and vice versa.\n* * {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `attributeToAttribute()`} &ndash;\n* Model attribute to view attribute and vice versa.\n*/\nvar Conversion = class {\n\t/**\n\t* Maps dispatchers group name to ConversionHelpers instances.\n\t*/\n\t_helpers = /* @__PURE__ */ new Map();\n\t_downcast;\n\t_upcast;\n\t/**\n\t* Creates a new conversion instance.\n\t*/\n\tconstructor(downcastDispatchers, upcastDispatchers) {\n\t\tthis._downcast = toArray(downcastDispatchers);\n\t\tthis._createConversionHelpers({\n\t\t\tname: \"downcast\",\n\t\t\tdispatchers: this._downcast,\n\t\t\tisDowncast: true\n\t\t});\n\t\tthis._upcast = toArray(upcastDispatchers);\n\t\tthis._createConversionHelpers({\n\t\t\tname: \"upcast\",\n\t\t\tdispatchers: this._upcast,\n\t\t\tisDowncast: false\n\t\t});\n\t}\n\t/**\n\t* Define an alias for registered dispatcher.\n\t*\n\t* ```ts\n\t* const conversion = new Conversion(\n\t* \t[ dataDowncastDispatcher, editingDowncastDispatcher ],\n\t* \tupcastDispatcher\n\t* );\n\t*\n\t* conversion.addAlias( 'dataDowncast', dataDowncastDispatcher );\n\t* ```\n\t*\n\t* @param alias An alias of a dispatcher.\n\t* @param dispatcher Dispatcher which should have an alias.\n\t*/\n\taddAlias(alias, dispatcher) {\n\t\tconst isDowncast = this._downcast.includes(dispatcher);\n\t\tif (!this._upcast.includes(dispatcher) && !isDowncast)\n /**\n\t\t* Trying to register an alias for a dispatcher that nas not been registered.\n\t\t*\n\t\t* @error conversion-add-alias-dispatcher-not-registered\n\t\t*/\n\t\tthrow new CKEditorError(\"conversion-add-alias-dispatcher-not-registered\", this);\n\t\tthis._createConversionHelpers({\n\t\t\tname: alias,\n\t\t\tdispatchers: [dispatcher],\n\t\t\tisDowncast\n\t\t});\n\t}\n\t/**\n\t* Provides a chainable API to assign converters to a conversion dispatchers group.\n\t*\n\t* If the given group name has not been registered, the\n\t* {@link module:utils/ckeditorerror~CKEditorError `conversion-for-unknown-group` error} is thrown.\n\t*\n\t* You can use conversion helpers available directly in the `for()` chain or your custom ones via\n\t* the {@link module:engine/conversion/conversionhelpers~ConversionHelpers#add `add()`} method.\n\t*\n\t* # Using built-in conversion helpers\n\t*\n\t* The `for()` chain comes with a set of conversion helpers which you can use like this:\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'downcast' )\n\t* \t.elementToElement( config1 ) // Adds an element-to-element downcast converter.\n\t* \t.attributeToElement( config2 ); // Adds an attribute-to-element downcast converter.\n\t*\n\t* editor.conversion.for( 'upcast' )\n\t* \t.elementToAttribute( config3 ); // Adds an element-to-attribute upcast converter.\n\t* ```\n\t*\n\t* Refer to the documentation of built-in conversion helpers to learn about their configuration options.\n\t*\n\t* * downcast (model-to-view) conversion helpers:\n\t*\n\t*\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`},\n\t*\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement `attributeToElement()`},\n\t*\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToAttribute `attributeToAttribute()`}.\n\t*\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToElement `markerToElement()`}.\n\t*\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToHighlight `markerToHighlight()`}.\n\t*\n\t* * upcast (view-to-model) conversion helpers:\n\t*\n\t*\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToElement `elementToElement()`},\n\t*\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToAttribute `elementToAttribute()`},\n\t*\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#attributeToAttribute `attributeToAttribute()`}.\n\t*\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToMarker `elementToMarker()`}.\n\t*\n\t* # Using custom conversion helpers\n\t*\n\t* If you need to implement an atypical converter, you can do so by calling:\n\t*\n\t* ```ts\n\t* editor.conversion.for( direction ).add( customHelper );\n\t* ```\n\t*\n\t* The `.add()` method takes exactly one parameter, which is a function. This function should accept one parameter that\n\t* is a dispatcher instance. The function should add an actual converter to the passed dispatcher instance.\n\t*\n\t* Example:\n\t*\n\t* ```ts\n\t* editor.conversion.for( 'upcast' ).add( dispatcher => {\n\t* \tdispatcher.on( 'element:a', ( evt, data, conversionApi ) => {\n\t* \t\t// Do something with a view <a> element.\n\t* \t} );\n\t* } );\n\t* ```\n\t*\n\t* Refer to the documentation of {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}\n\t* and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} to learn how to write\n\t* custom converters.\n\t*\n\t* @param groupName The name of dispatchers group to add the converters to.\n\t*/\n\tfor(groupName) {\n\t\tif (!this._helpers.has(groupName))\n /**\n\t\t* Trying to add a converter to an unknown dispatchers group.\n\t\t*\n\t\t* @error conversion-for-unknown-group\n\t\t*/\n\t\tthrow new CKEditorError(\"conversion-for-unknown-group\", this);\n\t\treturn this._helpers.get(groupName);\n\t}\n\t/**\n\t* Sets up converters between the model and the view that convert a model element to a view element (and vice versa).\n\t* For example, the model `<paragraph>Foo</paragraph>` is turned into `<p>Foo</p>` in the view.\n\t*\n\t* ```ts\n\t* // A simple conversion from the `paragraph` model element to the `<p>` view element (and vice versa).\n\t* editor.conversion.elementToElement( { model: 'paragraph', view: 'p' } );\n\t*\n\t* // Override other converters by specifying a converter definition with a higher priority.\n\t* editor.conversion.elementToElement( { model: 'paragraph', view: 'div', converterPriority: 'high' } );\n\t*\n\t* // View specified as an object instead of a string.\n\t* editor.conversion.elementToElement( {\n\t* \tmodel: 'fancyParagraph',\n\t* \tview: {\n\t* \t\tname: 'p',\n\t* \t\tclasses: 'fancy'\n\t* \t}\n\t* } );\n\t*\n\t* // Use `upcastAlso` to define other view elements that should also be converted to a `paragraph` element.\n\t* editor.conversion.elementToElement( {\n\t* \tmodel: 'paragraph',\n\t* \tview: 'p',\n\t* \tupcastAlso: [\n\t* \t\t'div',\n\t* \t\t{\n\t* \t\t\t// Any element with the `display: block` style.\n\t* \t\t\tstyles: {\n\t* \t\t\t\tdisplay: 'block'\n\t* \t\t\t}\n\t* \t\t}\n\t* \t]\n\t* } );\n\t*\n\t* // `upcastAlso` set as callback enables a conversion of a wide range of different view elements.\n\t* editor.conversion.elementToElement( {\n\t* \tmodel: 'heading',\n\t* \tview: 'h2',\n\t* \t// Convert \"heading-like\" paragraphs to headings.\n\t* \tupcastAlso: viewElement => {\n\t* \t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t*\n\t* \t\tif ( !fontSize ) {\n\t* \t\t\treturn null;\n\t* \t\t}\n\t*\n\t* \t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t*\n\t* \t\tif ( !match ) {\n\t* \t\t\treturn null;\n\t* \t\t}\n\t*\n\t* \t\tconst size = Number( match[ 1 ] );\n\t*\n\t* \t\tif ( size > 26 ) {\n\t* \t\t\t// Returned value can be an object with the matched properties.\n\t* \t\t\t// These properties will be \"consumed\" during the conversion.\n\t* \t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t*\n\t* \t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t* \t\t}\n\t*\n\t* \t\treturn null;\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* `definition.model` is a `String` with a model element name to convert from or to.\n\t*\n\t* @param definition The converter definition.\n\t*/\n\telementToElement(definition) {\n\t\tthis.for(\"downcast\").elementToElement(definition);\n\t\tfor (const { model, view } of _getAllUpcastDefinitions(definition)) this.for(\"upcast\").elementToElement({\n\t\t\tmodel,\n\t\t\tview,\n\t\t\tconverterPriority: definition.converterPriority\n\t\t});\n\t}\n\t/**\n\t* Sets up converters between the model and the view that convert a model attribute to a view element (and vice versa).\n\t* For example, a model text node with `\"Foo\"` as data and the `bold` attribute will be turned to `<strong>Foo</strong>` in the view.\n\t*\n\t* ```ts\n\t* // A simple conversion from the `bold=true` attribute to the `<strong>` view element (and vice versa).\n\t* editor.conversion.attributeToElement( { model: 'bold', view: 'strong' } );\n\t*\n\t* // Override other converters by specifying a converter definition with a higher priority.\n\t* editor.conversion.attributeToElement( { model: 'bold', view: 'b', converterPriority: 'high' } );\n\t*\n\t* // View specified as an object instead of a string.\n\t* editor.conversion.attributeToElement( {\n\t* \tmodel: 'bold',\n\t* \tview: {\n\t* \t\tname: 'span',\n\t* \t\tclasses: 'bold'\n\t* \t}\n\t* } );\n\t*\n\t* // Use `config.model.name` to define the conversion only from a given node type, `$text` in this case.\n\t* // The same attribute on different elements may then be handled by a different converter.\n\t* editor.conversion.attributeToElement( {\n\t* \tmodel: {\n\t* \t\tkey: 'textDecoration',\n\t* \t\tvalues: [ 'underline', 'lineThrough' ],\n\t* \t\tname: '$text'\n\t* \t},\n\t* \tview: {\n\t* \t\tunderline: {\n\t* \t\t\tname: 'span',\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'text-decoration': 'underline'\n\t* \t\t\t}\n\t* \t\t},\n\t* \t\tlineThrough: {\n\t* \t\t\tname: 'span',\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'text-decoration': 'line-through'\n\t* \t\t\t}\n\t* \t\t}\n\t* \t}\n\t* } );\n\t*\n\t* // Use `upcastAlso` to define other view elements that should also be converted to the `bold` attribute.\n\t* editor.conversion.attributeToElement( {\n\t* \tmodel: 'bold',\n\t* \tview: 'strong',\n\t* \tupcastAlso: [\n\t* \t\t'b',\n\t* \t\t{\n\t* \t\t\tname: 'span',\n\t* \t\t\tclasses: 'bold'\n\t* \t\t},\n\t* \t\t{\n\t* \t\t\tname: 'span',\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'font-weight': 'bold'\n\t* \t\t\t}\n\t* \t\t},\n\t* \t\tviewElement => {\n\t* \t\t\tconst fontWeight = viewElement.getStyle( 'font-weight' );\n\t*\n\t* \t\t\tif ( viewElement.is( 'element', 'span' ) && fontWeight && /\\d+/.test() && Number( fontWeight ) > 500 ) {\n\t* \t\t\t\t// Returned value can be an object with the matched properties.\n\t* \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t* \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t*\n\t* \t\t\t\treturn {\n\t* \t\t\t\t\tname: true,\n\t* \t\t\t\t\tstyles: [ 'font-weight' ]\n\t* \t\t\t\t};\n\t* \t\t\t}\n\t* \t\t}\n\t* \t]\n\t* } );\n\t*\n\t* // Conversion from and to a model attribute key whose value is an enum (`fontSize=big|small`).\n\t* // `upcastAlso` set as callback enables a conversion of a wide range of different view elements.\n\t* editor.conversion.attributeToElement( {\n\t* \tmodel: {\n\t* \t\tkey: 'fontSize',\n\t* \t\tvalues: [ 'big', 'small' ]\n\t* \t},\n\t* \tview: {\n\t* \t\tbig: {\n\t* \t\t\tname: 'span',\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'font-size': '1.2em'\n\t* \t\t\t}\n\t* \t\t},\n\t* \t\tsmall: {\n\t* \t\t\tname: 'span',\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'font-size': '0.8em'\n\t* \t\t\t}\n\t* \t\t}\n\t* \t},\n\t* \tupcastAlso: {\n\t* \t\tbig: viewElement => {\n\t* \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t*\n\t* \t\t\tif ( !fontSize ) {\n\t* \t\t\t\treturn null;\n\t* \t\t\t}\n\t*\n\t* \t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t*\n\t* \t\t\tif ( !match ) {\n\t* \t\t\t\treturn null;\n\t* \t\t\t}\n\t*\n\t* \t\t\tconst size = Number( match[ 1 ] );\n\t*\n\t* \t\t\tif ( viewElement.is( 'element', 'span' ) && size > 10 ) {\n\t* \t\t\t\t// Returned value can be an object with the matched properties.\n\t* \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t* \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t*\n\t* \t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t* \t\t\t}\n\t*\n\t* \t\t\treturn null;\n\t* \t\t},\n\t* \t\tsmall: viewElement => {\n\t* \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t*\n\t* \t\t\tif ( !fontSize ) {\n\t* \t\t\t\treturn null;\n\t* \t\t\t}\n\t*\n\t* \t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t*\n\t* \t\t\tif ( !match ) {\n\t* \t\t\t\treturn null;\n\t* \t\t\t}\n\t*\n\t* \t\t\tconst size = Number( match[ 1 ] );\n\t*\n\t* \t\t\tif ( viewElement.is( 'element', 'span' ) && size < 10 ) {\n\t* \t\t\t\t// Returned value can be an object with the matched properties.\n\t* \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t* \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t*\n\t* \t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t* \t\t\t}\n\t*\n\t* \t\t\treturn null;\n\t* \t\t}\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* The `definition.model` parameter specifies which model attribute should be converted from or to. It can be a `{ key, value }` object\n\t* describing the attribute key and value to convert or a `String` specifying just the attribute key (in such a case\n\t* `value` is set to `true`).\n\t*\n\t* @param definition The converter definition.\n\t*/\n\tattributeToElement(definition) {\n\t\tthis.for(\"downcast\").attributeToElement(definition);\n\t\tfor (const { model, view } of _getAllUpcastDefinitions(definition)) this.for(\"upcast\").elementToAttribute({\n\t\t\tview,\n\t\t\tmodel,\n\t\t\tconverterPriority: definition.converterPriority\n\t\t});\n\t}\n\t/**\n\t* Sets up converters between the model and the view that convert a model attribute to a view attribute (and vice versa). For example,\n\t* `<imageBlock src='foo.jpg'></imageBlock>` is converted to `<img src='foo.jpg'></img>` (the same attribute key and value).\n\t* This type of converters is intended to be used with {@link module:engine/model/element~ModelElement model element} nodes.\n\t* To convert the text attributes,\n\t* the {@link module:engine/conversion/conversion~Conversion#attributeToElement `attributeToElement converter`}should be set up.\n\t*\n\t* ```ts\n\t* // A simple conversion from the `source` model attribute to the `src` view attribute (and vice versa).\n\t* editor.conversion.attributeToAttribute( { model: 'source', view: 'src' } );\n\t*\n\t* // Attribute values are strictly specified.\n\t* editor.conversion.attributeToAttribute( {\n\t* \tmodel: {\n\t* \t\tname: 'imageInline',\n\t* \t\tkey: 'aside',\n\t* \t\tvalues: [ 'aside' ]\n\t* \t},\n\t* \tview: {\n\t* \t\taside: {\n\t* \t\t\tname: 'img',\n\t* \t\t\tkey: 'class',\n\t* \t\t\tvalue: [ 'aside', 'half-size' ]\n\t* \t\t}\n\t* \t}\n\t* } );\n\t*\n\t* // Set the style attribute.\n\t* editor.conversion.attributeToAttribute( {\n\t* \tmodel: {\n\t* \t\tname: 'imageInline',\n\t* \t\tkey: 'aside',\n\t* \t\tvalues: [ 'aside' ]\n\t* \t},\n\t* \tview: {\n\t* \t\taside: {\n\t* \t\t\tname: 'img',\n\t* \t\t\tkey: 'style',\n\t* \t\t\tvalue: {\n\t* \t\t\t\tfloat: 'right',\n\t* \t\t\t\twidth: '50%',\n\t* \t\t\t\tmargin: '5px'\n\t* \t\t\t}\n\t* \t\t}\n\t* \t}\n\t* } );\n\t*\n\t* // Conversion from and to a model attribute key whose value is an enum (`align=right|center`).\n\t* // Use `upcastAlso` to define other view elements that should also be converted to the `align=right` attribute.\n\t* editor.conversion.attributeToAttribute( {\n\t* \tmodel: {\n\t* \t\tkey: 'align',\n\t* \t\tvalues: [ 'right', 'center' ]\n\t* \t},\n\t* \tview: {\n\t* \t\tright: {\n\t* \t\t\tkey: 'class',\n\t* \t\t\tvalue: 'align-right'\n\t* \t\t},\n\t* \t\tcenter: {\n\t* \t\t\tkey: 'class',\n\t* \t\t\tvalue: 'align-center'\n\t* \t\t}\n\t* \t},\n\t* \tupcastAlso: {\n\t* \t\tright: {\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'text-align': 'right'\n\t* \t\t\t}\n\t* \t\t},\n\t* \t\tcenter: {\n\t* \t\t\tstyles: {\n\t* \t\t\t\t'text-align': 'center'\n\t* \t\t\t}\n\t* \t\t}\n\t* \t}\n\t* } );\n\t* ```\n\t*\n\t* The `definition.model` parameter specifies which model attribute should be converted from and to.\n\t* It can be a `{ key, [ values ], [ name ] }` object or a `String`, which will be treated like `{ key: definition.model }`.\n\t* The `key` property is the model attribute key to convert from and to.\n\t* The `values` are the possible model attribute values. If the `values` parameter is not set, the model attribute value\n\t* will be the same as the view attribute value.\n\t* If `name` is set, the conversion will be set up only for model elements with the given name.\n\t*\n\t* The `definition.view` parameter specifies which view attribute should be converted from and to.\n\t* It can be a `{ key, value, [ name ] }` object or a `String`, which will be treated like `{ key: definition.view }`.\n\t* The `key` property is the view attribute key to convert from and to.\n\t* The `value` is the view attribute value to convert from and to. If `definition.value` is not set, the view attribute value will be\n\t* the same as the model attribute value.\n\t* If `key` is `'class'`, `value` can be a `String` or an array of `String`s.\n\t* If `key` is `'style'`, `value` is an object with key-value pairs.\n\t* In other cases, `value` is a `String`.\n\t* If `name` is set, the conversion will be set up only for model elements with the given name.\n\t* If `definition.model.values` is set, `definition.view` is an object that assigns values from `definition.model.values`\n\t* to `{ key, value, [ name ] }` objects.\n\t*\n\t* `definition.upcastAlso` specifies which other matching view elements should also be upcast to the given model configuration.\n\t* If `definition.model.values` is set, `definition.upcastAlso` should be an object assigning values from `definition.model.values`\n\t* to {@link module:engine/view/matcher~MatcherPattern}s or arrays of {@link module:engine/view/matcher~MatcherPattern}s.\n\t*\n\t* **Note:** `definition.model` and `definition.view` form should be mirrored, so the same types of parameters should\n\t* be given in both parameters.\n\t*\n\t* @param definition The converter definition.\n\t* @param definition.model The model attribute to convert from and to.\n\t* @param definition.view The view attribute to convert from and to.\n\t* @param definition.upcastAlso Any view element matching `definition.upcastAlso` will also be converted to the given model attribute.\n\t* `definition.upcastAlso` is used only if `config.model.values` is specified.\n\t*/\n\tattributeToAttribute(definition) {\n\t\tthis.for(\"downcast\").attributeToAttribute(definition);\n\t\tfor (const { model, view } of _getAllUpcastDefinitions(definition)) this.for(\"upcast\").attributeToAttribute({\n\t\t\tview,\n\t\t\tmodel\n\t\t});\n\t}\n\t/**\n\t* Creates and caches conversion helpers for given dispatchers group.\n\t*\n\t* @param options Group name.\n\t* @param options.name Group name.\n\t* @param options.dispatchers Dispatchers to register.\n\t* @param options.isDowncast Whether downcast group.\n\t*/\n\t_createConversionHelpers({ name, dispatchers, isDowncast }) {\n\t\tif (this._helpers.has(name))\n /**\n\t\t* Trying to register a group name that has already been registered.\n\t\t*\n\t\t* @error conversion-group-exists\n\t\t*/\n\t\tthrow new CKEditorError(\"conversion-group-exists\", this);\n\t\tconst helpers = isDowncast ? new DowncastHelpers(dispatchers) : new UpcastHelpers(dispatchers);\n\t\tthis._helpers.set(name, helpers);\n\t}\n};\n/**\n* Helper function that creates a joint array out of an item passed in `definition.view` and items passed in\n* `definition.upcastAlso`.\n*/\nfunction* _getAllUpcastDefinitions(definition) {\n\tif (definition.model.values) for (const value of definition.model.values) {\n\t\tconst model = {\n\t\t\tkey: definition.model.key,\n\t\t\tvalue\n\t\t};\n\t\tconst view = definition.view[value];\n\t\tyield* _getUpcastDefinition(model, view, definition.upcastAlso ? definition.upcastAlso[value] : void 0);\n\t}\n\telse yield* _getUpcastDefinition(definition.model, definition.view, definition.upcastAlso);\n}\nfunction* _getUpcastDefinition(model, view, upcastAlso) {\n\tyield {\n\t\tmodel,\n\t\tview\n\t};\n\tif (upcastAlso) for (const upcastAlsoItem of toArray(upcastAlso)) yield {\n\t\tmodel,\n\t\tview: upcastAlsoItem\n\t};\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/dataprocessor/xmldataprocessor\n*/\n/**\n* The XML data processor class.\n* This data processor implementation uses XML as input and output data.\n* This class is needed because unlike HTML, XML allows to use any tag with any value.\n* For example, `<link>Text</link>` is a valid XML but invalid HTML.\n*/\nvar XmlDataProcessor = class {\n\t/**\n\t* A list of namespaces allowed to use in the XML input.\n\t*\n\t* For example, registering namespaces [ 'attribute', 'container' ] allows to use `<attirbute:tagName></attribute:tagName>`\n\t* and `<container:tagName></container:tagName>` input. It is mainly for debugging.\n\t*/\n\tnamespaces;\n\t/**\n\t* DOM parser instance used to parse an XML string to an XML document.\n\t*/\n\tdomParser;\n\t/**\n\t* DOM converter used to convert DOM elements to view elements.\n\t*/\n\tdomConverter;\n\t/**\n\t* A basic HTML writer instance used to convert DOM elements to an XML string.\n\t* There is no need to use a dedicated XML writer because the basic HTML writer works well in this case.\n\t*/\n\thtmlWriter;\n\tskipComments = true;\n\t/**\n\t* Creates a new instance of the XML data processor class.\n\t*\n\t* @param document The view document instance.\n\t* @param options Configuration options.\n\t* @param options.namespaces A list of namespaces allowed to use in the XML input.\n\t*/\n\tconstructor(document, options = {}) {\n\t\tthis.namespaces = options.namespaces || [];\n\t\tthis.domParser = new DOMParser();\n\t\tthis.domConverter = new ViewDomConverter(document, { renderingMode: \"data\" });\n\t\tthis.htmlWriter = new BasicHtmlWriter();\n\t}\n\t/**\n\t* Converts the provided {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment}\n\t* to data format &ndash; in this case an XML string.\n\t*\n\t* @returns An XML string.\n\t*/\n\ttoData(viewFragment) {\n\t\tconst domFragment = this.domConverter.viewToDom(viewFragment);\n\t\treturn this.htmlWriter.getHtml(domFragment);\n\t}\n\t/**\n\t* Converts the provided XML string to a view tree.\n\t*\n\t* @param data An XML string.\n\t* @returns A converted view element.\n\t*/\n\ttoView(data) {\n\t\tconst domFragment = this._toDom(data);\n\t\treturn this.domConverter.domToView(domFragment, {\n\t\t\tkeepOriginalCase: true,\n\t\t\tskipComments: this.skipComments\n\t\t});\n\t}\n\t/**\n\t* Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t* and not processed during the conversion from XML to view elements.\n\t*\n\t* The raw data can be later accessed by a\n\t* {@link module:engine/view/element~ViewElement#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t*\n\t* @param pattern Pattern matching all view elements whose content should be treated as raw data.\n\t*/\n\tregisterRawContentMatcher(pattern) {\n\t\tthis.domConverter.registerRawContentMatcher(pattern);\n\t}\n\t/**\n\t* If the processor is set to use marked fillers, it will insert `&nbsp;` fillers wrapped in `<span>` elements\n\t* (`<span data-cke-filler=\"true\">&nbsp;</span>`) instead of regular `&nbsp;` characters.\n\t*\n\t* This mode allows for a more precise handling of block fillers (so they do not leak into editor content) but\n\t* bloats the editor data with additional markup.\n\t*\n\t* This mode may be required by some features and will be turned on by them automatically.\n\t*\n\t* @param type Whether to use the default or the marked `&nbsp;` block fillers.\n\t*/\n\tuseFillerType(type) {\n\t\tthis.domConverter.blockFillerMode = type == \"marked\" ? \"markedNbsp\" : \"nbsp\";\n\t}\n\t/**\n\t* Converts an XML string to its DOM representation. Returns a document fragment containing nodes parsed from\n\t* the provided data.\n\t*/\n\t_toDom(data) {\n\t\tdata = `<xml ${this.namespaces.map((nsp) => `xmlns:${nsp}=\"nsp\"`).join(\" \")}>${data}</xml>`;\n\t\tconst parsedDocument = this.domParser.parseFromString(data, \"text/xml\");\n\t\tconst parserError = parsedDocument.querySelector(\"parsererror\");\n\t\tif (parserError) throw new Error(\"Parse error - \" + parserError.textContent);\n\t\tconst fragment = parsedDocument.createDocumentFragment();\n\t\tconst nodes = parsedDocument.documentElement.childNodes;\n\t\twhile (nodes.length > 0) fragment.appendChild(nodes[0]);\n\t\treturn fragment;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Abstract base operation class.\n*/\nvar Operation = class {\n\t/**\n\t* {@link module:engine/model/document~ModelDocument#version} on which operation can be applied. If you try to\n\t* {@link module:engine/model/model~Model#applyOperation apply} operation with different base version than the\n\t* {@link module:engine/model/document~ModelDocument#version document version} the\n\t* {@link module:utils/ckeditorerror~CKEditorError model-document-applyOperation-wrong-version} error is thrown.\n\t*/\n\tbaseVersion;\n\t/**\n\t* Defines whether operation is executed on attached or detached {@link module:engine/model/item~ModelItem items}.\n\t*/\n\tisDocumentOperation;\n\t/**\n\t* {@link module:engine/model/batch~Batch Batch} to which the operation is added or `null` if the operation is not\n\t* added to any batch yet.\n\t*\n\t* Note, that a {@link #isDocumentOperation non-document operation} has this property always set to `null`, and is never added\n\t* to any batch.\n\t*/\n\tbatch;\n\t/**\n\t* Base operation constructor.\n\t*\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(baseVersion) {\n\t\tthis.baseVersion = baseVersion;\n\t\tthis.isDocumentOperation = this.baseVersion !== null;\n\t\tthis.batch = null;\n\t}\n\t/**\n\t* Checks whether the operation's parameters are correct and the operation can be correctly executed. Throws\n\t* an error if operation is not valid.\n\t*\n\t* @internal\n\t*/\n\t_validate() {}\n\t/**\n\t* Custom toJSON method to solve child-parent circular dependencies.\n\t*\n\t* @returns Clone of this object with the operation property replaced with string.\n\t*/\n\ttoJSON() {\n\t\tconst json = Object.assign({}, this);\n\t\tjson.__className = this.constructor.className;\n\t\tdelete json.batch;\n\t\tdelete json.isDocumentOperation;\n\t\treturn json;\n\t}\n\t/**\n\t* Name of the operation class used for serialization.\n\t*/\n\tstatic get className() {\n\t\treturn \"Operation\";\n\t}\n\t/**\n\t* Creates `Operation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\treturn new this(json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/utils\n*/\n/**\n* Inserts given nodes at given position.\n*\n* @internal\n* @param position Position at which nodes should be inserted.\n* @param nodes Nodes to insert.\n* @returns Range spanning over inserted elements.\n*/\nfunction _insert(position, nodes) {\n\tconst normalizedNodes = _normalizeNodes(nodes);\n\tconst offset = normalizedNodes.reduce((sum, node) => sum + node.offsetSize, 0);\n\tconst parent = position.parent;\n\t_splitNodeAtPosition(position);\n\tconst index = position.index;\n\tparent._insertChild(index, normalizedNodes);\n\t_mergeNodesAtIndex(parent, index + normalizedNodes.length);\n\t_mergeNodesAtIndex(parent, index);\n\treturn new ModelRange(position, position.getShiftedBy(offset));\n}\n/**\n* Removed nodes in given range. Only {@link module:engine/model/range~ModelRange#isFlat flat} ranges are accepted.\n*\n* @internal\n* @param range Range containing nodes to remove.\n*/\nfunction _remove(range) {\n\tif (!range.isFlat)\n /**\n\t* Trying to remove a range which starts and ends in different element.\n\t*\n\t* @error operation-utils-remove-range-not-flat\n\t*/\n\tthrow new CKEditorError(\"operation-utils-remove-range-not-flat\", this);\n\tconst parent = range.start.parent;\n\t_splitNodeAtPosition(range.start);\n\t_splitNodeAtPosition(range.end);\n\tconst removed = parent._removeChildren(range.start.index, range.end.index - range.start.index);\n\t_mergeNodesAtIndex(parent, range.start.index);\n\treturn removed;\n}\n/**\n* Moves nodes in given range to given target position. Only {@link module:engine/model/range~ModelRange#isFlat flat} ranges are accepted.\n*\n* @internal\n* @param sourceRange Range containing nodes to move.\n* @param targetPosition Position to which nodes should be moved.\n* @returns Range containing moved nodes.\n*/\nfunction _move(sourceRange, targetPosition) {\n\tif (!sourceRange.isFlat)\n /**\n\t* Trying to move a range which starts and ends in different element.\n\t*\n\t* @error operation-utils-move-range-not-flat\n\t*/\n\tthrow new CKEditorError(\"operation-utils-move-range-not-flat\", this);\n\tconst nodes = _remove(sourceRange);\n\ttargetPosition = targetPosition._getTransformedByDeletion(sourceRange.start, sourceRange.end.offset - sourceRange.start.offset);\n\treturn _insert(targetPosition, nodes);\n}\n/**\n* Sets given attribute on nodes in given range. The attributes are only set on top-level nodes of the range, not on its children.\n*\n* @internal\n* @param range Range containing nodes that should have the attribute set. Must be a flat range.\n* @param key Key of attribute to set.\n* @param value Attribute value.\n*/\nfunction _setAttribute(range, key, value) {\n\t_splitNodeAtPosition(range.start);\n\t_splitNodeAtPosition(range.end);\n\tfor (const item of range.getItems({ shallow: true })) {\n\t\tconst node = item.is(\"$textProxy\") ? item.textNode : item;\n\t\tif (value !== null) node._setAttribute(key, value);\n\t\telse node._removeAttribute(key);\n\t\t_mergeNodesAtIndex(node.parent, node.index);\n\t}\n\t_mergeNodesAtIndex(range.end.parent, range.end.index);\n}\n/**\n* Normalizes given object or an array of objects to an array of {@link module:engine/model/node~ModelNode nodes}. See\n* {@link ~ModelNodeSet NodeSet} for details on how normalization is performed.\n*\n* @internal\n* @param nodes Objects to normalize.\n* @returns Normalized nodes.\n*/\nfunction _normalizeNodes(nodes) {\n\tconst normalized = [];\n\tfunction convert(nodes) {\n\t\tif (typeof nodes == \"string\") normalized.push(new ModelText(nodes));\n\t\telse if (nodes instanceof ModelTextProxy) normalized.push(new ModelText(nodes.data, nodes.getAttributes()));\n\t\telse if (nodes instanceof ModelNode) normalized.push(nodes);\n\t\telse if (isIterable(nodes)) for (const node of nodes) convert(node);\n\t}\n\tconvert(nodes);\n\tfor (let i = 1; i < normalized.length; i++) {\n\t\tconst node = normalized[i];\n\t\tconst prev = normalized[i - 1];\n\t\tif (node instanceof ModelText && prev instanceof ModelText && _haveSameAttributes(node, prev)) {\n\t\t\tnormalized.splice(i - 1, 2, new ModelText(prev.data + node.data, prev.getAttributes()));\n\t\t\ti--;\n\t\t}\n\t}\n\treturn normalized;\n}\n/**\n* Checks if nodes before and after given index in given element are {@link module:engine/model/text~ModelText text nodes} and\n* merges them into one node if they have same attributes.\n*\n* Merging is done by removing two text nodes and inserting a new text node containing data from both merged text nodes.\n*\n* @param element Parent element of nodes to merge.\n* @param index Index between nodes to merge.\n*/\nfunction _mergeNodesAtIndex(element, index) {\n\tconst nodeBefore = element.getChild(index - 1);\n\tconst nodeAfter = element.getChild(index);\n\tif (nodeBefore && nodeAfter && nodeBefore.is(\"$text\") && nodeAfter.is(\"$text\") && _haveSameAttributes(nodeBefore, nodeAfter)) {\n\t\tconst mergedNode = new ModelText(nodeBefore.data + nodeAfter.data, nodeBefore.getAttributes());\n\t\telement._removeChildren(index - 1, 2);\n\t\telement._insertChild(index - 1, mergedNode);\n\t}\n}\n/**\n* Checks if given position is in a text node, and if so, splits the text node in two text nodes, each of them\n* containing a part of original text node.\n*\n* @param position Position at which node should be split.\n*/\nfunction _splitNodeAtPosition(position) {\n\tconst textNode = position.textNode;\n\tconst element = position.parent;\n\tif (textNode) {\n\t\tconst offsetDiff = position.offset - textNode.startOffset;\n\t\tconst index = textNode.index;\n\t\telement._removeChildren(index, 1);\n\t\tconst firstPart = new ModelText(textNode.data.substr(0, offsetDiff), textNode.getAttributes());\n\t\tconst secondPart = new ModelText(textNode.data.substr(offsetDiff), textNode.getAttributes());\n\t\telement._insertChild(index, [firstPart, secondPart]);\n\t}\n}\n/**\n* Checks whether two given nodes have same attributes.\n*\n* @param nodeA Node to check.\n* @param nodeB Node to check.\n* @returns `true` if nodes have same attributes, `false` otherwise.\n*/\nfunction _haveSameAttributes(nodeA, nodeB) {\n\tconst iteratorA = nodeA.getAttributes();\n\tconst iteratorB = nodeB.getAttributes();\n\tfor (const attr of iteratorA) {\n\t\tif (attr[1] !== nodeB.getAttribute(attr[0])) return false;\n\t\titeratorB.next();\n\t}\n\treturn iteratorB.next().done;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/moveoperation\n*/\n/**\n* Operation to move a range of {@link module:engine/model/item~ModelItem model items}\n* to given {@link module:engine/model/position~ModelPosition target position}.\n*/\nvar MoveOperation = class MoveOperation extends Operation {\n\t/**\n\t* Position before the first {@link module:engine/model/item~ModelItem model item} to move.\n\t*/\n\tsourcePosition;\n\t/**\n\t* Offset size of moved range.\n\t*/\n\thowMany;\n\t/**\n\t* Position at which moved nodes will be inserted.\n\t*/\n\ttargetPosition;\n\t/**\n\t* Creates a move operation.\n\t*\n\t* @param sourcePosition Position before the first {@link module:engine/model/item~ModelItem model item} to move.\n\t* @param howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at\n\t* `sourcePosition` with offset shifted by `howMany`.\n\t* @param targetPosition Position at which moved nodes will be inserted.\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(sourcePosition, howMany, targetPosition, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.sourcePosition = sourcePosition.clone();\n\t\tthis.sourcePosition.stickiness = \"toNext\";\n\t\tthis.howMany = howMany;\n\t\tthis.targetPosition = targetPosition.clone();\n\t\tthis.targetPosition.stickiness = \"toNone\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\tif (this.targetPosition.root.rootName == this.sourcePosition.root.rootName) return \"move\";\n\t\telse if (this.targetPosition.root.rootName == \"$graveyard\") return \"remove\";\n\t\telse if (this.sourcePosition.root.rootName == \"$graveyard\") return \"reinsert\";\n\t\treturn \"move\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\treturn [this.sourceRange, ModelRange._createFromPositionAndShift(this.targetPosition, 0)];\n\t}\n\t/**\n\t* Returns the range that is moved by this operation. This is equal to a range starting at {@link #sourcePosition} spanning over\n\t* {@link #howMany} nodes.\n\t*/\n\tget sourceRange() {\n\t\treturn ModelRange._createFromPositionAndShift(this.sourcePosition, this.howMany);\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*/\n\tclone() {\n\t\treturn new MoveOperation(this.sourcePosition, this.howMany, this.targetPosition, this.baseVersion);\n\t}\n\t/**\n\t* Returns the start position of the moved range after it got moved. This may be different than\n\t* {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition} in some cases, i.e. when a range is moved\n\t* inside the same parent but {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition targetPosition}\n\t* is after {@link module:engine/model/operation/moveoperation~MoveOperation#sourcePosition sourcePosition}.\n\t*\n\t* ```\n\t* vv vv\n\t* abcdefg ===> adefbcg\n\t* ^ ^\n\t* targetPos movedRangeStart\n\t* offset 6 offset 4\n\t*```\n\t*/\n\tgetMovedRangeStart() {\n\t\treturn this.targetPosition._getTransformedByDeletion(this.sourcePosition, this.howMany);\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\tconst newTargetPosition = this.sourcePosition._getTransformedByInsertion(this.targetPosition, this.howMany);\n\t\treturn new MoveOperation(this.getMovedRangeStart(), this.howMany, newTargetPosition, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_validate() {\n\t\tconst sourceElement = this.sourcePosition.parent;\n\t\tconst targetElement = this.targetPosition.parent;\n\t\tconst sourceOffset = this.sourcePosition.offset;\n\t\tconst targetOffset = this.targetPosition.offset;\n\t\tif (sourceOffset + this.howMany > sourceElement.maxOffset)\n /**\n\t\t* The nodes which should be moved do not exist.\n\t\t*\n\t\t* @error move-operation-nodes-do-not-exist\n\t\t*/\n\t\tthrow new CKEditorError(\"move-operation-nodes-do-not-exist\", this);\n\t\telse if (sourceElement === targetElement && sourceOffset < targetOffset && targetOffset < sourceOffset + this.howMany)\n /**\n\t\t* Trying to move a range of nodes into the middle of that range.\n\t\t*\n\t\t* @error move-operation-range-into-itself\n\t\t*/\n\t\tthrow new CKEditorError(\"move-operation-range-into-itself\", this);\n\t\telse if (this.sourcePosition.root == this.targetPosition.root) {\n\t\t\tif (compareArrays(this.sourcePosition.getParentPath(), this.targetPosition.getParentPath()) == \"prefix\") {\n\t\t\t\tconst i = this.sourcePosition.path.length - 1;\n\t\t\t\tif (this.targetPosition.path[i] >= sourceOffset && this.targetPosition.path[i] < sourceOffset + this.howMany)\n /**\n\t\t\t\t* Trying to move a range of nodes into one of nodes from that range.\n\t\t\t\t*\n\t\t\t\t* @error move-operation-node-into-itself\n\t\t\t\t*/\n\t\t\t\tthrow new CKEditorError(\"move-operation-node-into-itself\", this);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\t_move(this.sourceRange, this.targetPosition);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.sourcePosition = this.sourcePosition.toJSON();\n\t\tjson.targetPosition = this.targetPosition.toJSON();\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"MoveOperation\";\n\t}\n\t/**\n\t* Creates `MoveOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\tconst sourcePosition = ModelPosition.fromJSON(json.sourcePosition, document);\n\t\tconst targetPosition = ModelPosition.fromJSON(json.targetPosition, document);\n\t\treturn new this(sourcePosition, json.howMany, targetPosition, json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/insertoperation\n*/\n/**\n* Operation to insert one or more nodes at given position in the model.\n*/\nvar InsertOperation = class InsertOperation extends Operation {\n\t/**\n\t* Position of insertion.\n\t*\n\t* @readonly\n\t*/\n\tposition;\n\t/**\n\t* List of nodes to insert.\n\t*\n\t* @readonly\n\t*/\n\tnodes;\n\t/**\n\t* Flag deciding how the operation should be transformed. If set to `true`, nodes might get additional attributes\n\t* during operational transformation. This happens when the operation insertion position is inside of a range\n\t* where attributes have changed.\n\t*/\n\tshouldReceiveAttributes;\n\t/**\n\t* Creates an insert operation.\n\t*\n\t* @param position Position of insertion.\n\t* @param nodes The list of nodes to be inserted.\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(position, nodes, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.position = position.clone();\n\t\tthis.position.stickiness = \"toNone\";\n\t\tthis.nodes = new ModelNodeList(_normalizeNodes(nodes));\n\t\tthis.shouldReceiveAttributes = false;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\treturn \"insert\";\n\t}\n\t/**\n\t* Total offset size of inserted nodes.\n\t*/\n\tget howMany() {\n\t\treturn this.nodes.maxOffset;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\treturn this.position.clone();\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*/\n\tclone() {\n\t\tconst nodes = new ModelNodeList([...this.nodes].map((node) => node._clone(true)));\n\t\tconst insert = new InsertOperation(this.position, nodes, this.baseVersion);\n\t\tinsert.shouldReceiveAttributes = this.shouldReceiveAttributes;\n\t\treturn insert;\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\tconst graveyard = this.position.root.document.graveyard;\n\t\tconst gyPosition = new ModelPosition(graveyard, [0]);\n\t\treturn new MoveOperation(this.position, this.nodes.maxOffset, gyPosition, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_validate() {\n\t\tconst targetElement = this.position.parent;\n\t\tif (!targetElement || targetElement.maxOffset < this.position.offset)\n /**\n\t\t* Insertion position is invalid.\n\t\t*\n\t\t* @error insert-operation-position-invalid\n\t\t*/\n\t\tthrow new CKEditorError(\"insert-operation-position-invalid\", this);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\tconst originalNodes = this.nodes;\n\t\tthis.nodes = new ModelNodeList([...originalNodes].map((node) => node._clone(true)));\n\t\t_insert(this.position, originalNodes);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.position = this.position.toJSON();\n\t\tjson.nodes = this.nodes.toJSON();\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"InsertOperation\";\n\t}\n\t/**\n\t* Creates `InsertOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\tconst children = [];\n\t\tfor (const child of json.nodes) if (child.name) children.push(ModelElement.fromJSON(child));\n\t\telse children.push(ModelText.fromJSON(child));\n\t\tconst insert = new InsertOperation(ModelPosition.fromJSON(json.position, document), children, json.baseVersion);\n\t\tinsert.shouldReceiveAttributes = json.shouldReceiveAttributes;\n\t\treturn insert;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/splitoperation\n*/\n/**\n* Operation to split {@link module:engine/model/element~ModelElement an element} at given\n* {@link module:engine/model/operation/splitoperation~SplitOperation#splitPosition split position} into two elements,\n* both containing a part of the element's original content.\n*/\nvar SplitOperation = class SplitOperation extends Operation {\n\t/**\n\t* Position at which an element should be split.\n\t*/\n\tsplitPosition;\n\t/**\n\t* Total offset size of elements that are in the split element after `position`.\n\t*/\n\thowMany;\n\t/**\n\t* Position at which the clone of split element (or element from graveyard) will be inserted.\n\t*/\n\tinsertionPosition;\n\t/**\n\t* Position in the graveyard root before the element which should be used as a parent of the nodes after `position`.\n\t* If it is not set, a copy of the the `position` parent will be used.\n\t*\n\t* The default behavior is to clone the split element. Element from graveyard is used during undo.\n\t*/\n\tgraveyardPosition;\n\t/**\n\t* Creates a split operation.\n\t*\n\t* @param splitPosition Position at which an element should be split.\n\t* @param howMany Total offset size of elements that are in the split element after `position`.\n\t* @param insertionPosition Position at which the clone of split element (or element from graveyard) will be inserted.\n\t* @param graveyardPosition Position in the graveyard root before the element which\n\t* should be used as a parent of the nodes after `position`. If it is not set, a copy of the the `position` parent will be used.\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(splitPosition, howMany, insertionPosition, graveyardPosition, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.splitPosition = splitPosition.clone();\n\t\tthis.splitPosition.stickiness = \"toNext\";\n\t\tthis.howMany = howMany;\n\t\tthis.insertionPosition = insertionPosition;\n\t\tthis.graveyardPosition = graveyardPosition ? graveyardPosition.clone() : null;\n\t\tif (this.graveyardPosition) this.graveyardPosition.stickiness = \"toNext\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\treturn \"split\";\n\t}\n\t/**\n\t* Position inside the new clone of a split element.\n\t*\n\t* This is a position where nodes that are after the split position will be moved to.\n\t*/\n\tget moveTargetPosition() {\n\t\tconst path = this.insertionPosition.path.slice();\n\t\tpath.push(0);\n\t\treturn new ModelPosition(this.insertionPosition.root, path);\n\t}\n\t/**\n\t* Artificial range that contains all the nodes from the split element that will be moved to the new element.\n\t* The range starts at {@link #splitPosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.\n\t*/\n\tget movedRange() {\n\t\tconst end = this.splitPosition.getShiftedBy(Number.POSITIVE_INFINITY);\n\t\treturn new ModelRange(this.splitPosition, end);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\tconst ranges = [ModelRange._createFromPositionAndShift(this.splitPosition, 0), ModelRange._createFromPositionAndShift(this.insertionPosition, 0)];\n\t\tif (this.graveyardPosition) ranges.push(ModelRange._createFromPositionAndShift(this.graveyardPosition, 0));\n\t\treturn ranges;\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*\n\t* @returns Clone of this operation.\n\t*/\n\tclone() {\n\t\treturn new SplitOperation(this.splitPosition, this.howMany, this.insertionPosition, this.graveyardPosition, this.baseVersion);\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\tconst graveyard = this.splitPosition.root.document.graveyard;\n\t\tconst graveyardPosition = new ModelPosition(graveyard, [0]);\n\t\treturn new MergeOperation(this.moveTargetPosition, this.howMany, this.splitPosition, graveyardPosition, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_validate() {\n\t\tconst element = this.splitPosition.parent;\n\t\tconst offset = this.splitPosition.offset;\n\t\tif (!element || element.maxOffset < offset)\n /**\n\t\t* Split position is invalid.\n\t\t*\n\t\t* @error split-operation-position-invalid\n\t\t*/\n\t\tthrow new CKEditorError(\"split-operation-position-invalid\", this);\n\t\telse if (!element.parent)\n /**\n\t\t* Cannot split root element.\n\t\t*\n\t\t* @error split-operation-split-in-root\n\t\t*/\n\t\tthrow new CKEditorError(\"split-operation-split-in-root\", this);\n\t\telse if (this.howMany !== Number.NEGATIVE_INFINITY && this.howMany != element.maxOffset - this.splitPosition.offset)\n /**\n\t\t* Split operation specifies wrong number of nodes to move.\n\t\t*\n\t\t* @error split-operation-how-many-invalid\n\t\t*/\n\t\tthrow new CKEditorError(\"split-operation-how-many-invalid\", this);\n\t\telse if (this.graveyardPosition && !this.graveyardPosition.nodeAfter)\n /**\n\t\t* Graveyard position invalid.\n\t\t*\n\t\t* @error split-operation-graveyard-position-invalid\n\t\t*/\n\t\tthrow new CKEditorError(\"split-operation-graveyard-position-invalid\", this);\n\t\tthis.howMany = this.splitPosition.parent.maxOffset - this.splitPosition.offset;\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\tconst splitElement = this.splitPosition.parent;\n\t\tif (this.graveyardPosition) _move(ModelRange._createFromPositionAndShift(this.graveyardPosition, 1), this.insertionPosition);\n\t\telse {\n\t\t\tconst newElement = splitElement._clone();\n\t\t\t_insert(this.insertionPosition, newElement);\n\t\t}\n\t\tconst sourceRange = new ModelRange(ModelPosition._createAt(splitElement, this.splitPosition.offset), ModelPosition._createAt(splitElement, splitElement.maxOffset));\n\t\t_move(sourceRange, this.moveTargetPosition);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.splitPosition = this.splitPosition.toJSON();\n\t\tjson.insertionPosition = this.insertionPosition.toJSON();\n\t\tif (this.graveyardPosition) json.graveyardPosition = this.graveyardPosition.toJSON();\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"SplitOperation\";\n\t}\n\t/**\n\t* Helper function that returns a default insertion position basing on given `splitPosition`. The default insertion\n\t* position is after the split element.\n\t*/\n\tstatic getInsertionPosition(splitPosition) {\n\t\tconst path = splitPosition.path.slice(0, -1);\n\t\tpath[path.length - 1]++;\n\t\treturn new ModelPosition(splitPosition.root, path, \"toPrevious\");\n\t}\n\t/**\n\t* Creates `SplitOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\tconst splitPosition = ModelPosition.fromJSON(json.splitPosition, document);\n\t\tconst insertionPosition = ModelPosition.fromJSON(json.insertionPosition, document);\n\t\tconst graveyardPosition = json.graveyardPosition ? ModelPosition.fromJSON(json.graveyardPosition, document) : null;\n\t\treturn new this(splitPosition, json.howMany, insertionPosition, graveyardPosition, json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/mergeoperation\n*/\n/**\n* Operation to merge two {@link module:engine/model/element~ModelElement elements}.\n*\n* The merged element is the parent of {@link ~MergeOperation#sourcePosition} and it is merged into the parent of\n* {@link ~MergeOperation#targetPosition}. All nodes from the merged element are moved to {@link ~MergeOperation#targetPosition}.\n*\n* The merged element is moved to the graveyard at {@link ~MergeOperation#graveyardPosition}.\n*/\nvar MergeOperation = class MergeOperation extends Operation {\n\t/**\n\t* Position inside the merged element. All nodes from that element after that position will be moved to {@link #targetPosition}.\n\t*/\n\tsourcePosition;\n\t/**\n\t* Summary offset size of nodes which will be moved from the merged element to the new parent.\n\t*/\n\thowMany;\n\t/**\n\t* Position which the nodes from the merged elements will be moved to.\n\t*/\n\ttargetPosition;\n\t/**\n\t* Position in graveyard to which the merged element will be moved.\n\t*/\n\tgraveyardPosition;\n\t/**\n\t* Creates a merge operation.\n\t*\n\t* @param sourcePosition Position inside the merged element. All nodes from that\n\t* element after that position will be moved to {@link #targetPosition}.\n\t* @param howMany Summary offset size of nodes which will be moved from the merged element to the new parent.\n\t* @param targetPosition Position which the nodes from the merged elements will be moved to.\n\t* @param graveyardPosition Position in graveyard to which the merged element will be moved.\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(sourcePosition, howMany, targetPosition, graveyardPosition, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.sourcePosition = sourcePosition.clone();\n\t\tthis.sourcePosition.stickiness = \"toPrevious\";\n\t\tthis.howMany = howMany;\n\t\tthis.targetPosition = targetPosition.clone();\n\t\tthis.targetPosition.stickiness = \"toNext\";\n\t\tthis.graveyardPosition = graveyardPosition.clone();\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\treturn \"merge\";\n\t}\n\t/**\n\t* Position before the merged element (which will be deleted).\n\t*/\n\tget deletionPosition() {\n\t\treturn new ModelPosition(this.sourcePosition.root, this.sourcePosition.path.slice(0, -1));\n\t}\n\t/**\n\t* Artificial range that contains all the nodes from the merged element that will be moved to {@link ~MergeOperation#sourcePosition}.\n\t* The range starts at {@link ~MergeOperation#sourcePosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.\n\t*/\n\tget movedRange() {\n\t\tconst end = this.sourcePosition.getShiftedBy(Number.POSITIVE_INFINITY);\n\t\treturn new ModelRange(this.sourcePosition, end);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\tconst mergedElement = this.sourcePosition.parent;\n\t\treturn [\n\t\t\tModelRange._createOn(mergedElement),\n\t\t\tModelRange._createFromPositionAndShift(this.targetPosition, 0),\n\t\t\tModelRange._createFromPositionAndShift(this.graveyardPosition, 0)\n\t\t];\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*/\n\tclone() {\n\t\treturn new MergeOperation(this.sourcePosition, this.howMany, this.targetPosition, this.graveyardPosition, this.baseVersion);\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\tconst targetPosition = this.targetPosition._getTransformedByMergeOperation(this);\n\t\tconst path = this.sourcePosition.path.slice(0, -1);\n\t\tconst insertionPosition = new ModelPosition(this.sourcePosition.root, path)._getTransformedByMergeOperation(this);\n\t\treturn new SplitOperation(targetPosition, this.howMany, insertionPosition, this.graveyardPosition, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_validate() {\n\t\tconst sourceElement = this.sourcePosition.parent;\n\t\tconst targetElement = this.targetPosition.parent;\n\t\tif (!sourceElement.parent)\n /**\n\t\t* Merge source position is invalid. The element to be merged must have a parent node.\n\t\t*\n\t\t* @error merge-operation-source-position-invalid\n\t\t*/\n\t\tthrow new CKEditorError(\"merge-operation-source-position-invalid\", this);\n\t\telse if (!targetElement.parent)\n /**\n\t\t* Merge target position is invalid. The element to be merged must have a parent node.\n\t\t*\n\t\t* @error merge-operation-target-position-invalid\n\t\t*/\n\t\tthrow new CKEditorError(\"merge-operation-target-position-invalid\", this);\n\t\telse if (this.howMany !== Number.NEGATIVE_INFINITY && this.howMany != sourceElement.maxOffset)\n /**\n\t\t* Merge operation specifies wrong number of nodes to move.\n\t\t*\n\t\t* @error merge-operation-how-many-invalid\n\t\t*/\n\t\tthrow new CKEditorError(\"merge-operation-how-many-invalid\", this);\n\t\tthis.howMany = this.sourcePosition.parent.maxOffset;\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\tconst mergedElement = this.sourcePosition.parent;\n\t\tconst sourceRange = ModelRange._createIn(mergedElement);\n\t\t_move(sourceRange, this.targetPosition);\n\t\t_move(ModelRange._createOn(mergedElement), this.graveyardPosition);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.sourcePosition = json.sourcePosition.toJSON();\n\t\tjson.targetPosition = json.targetPosition.toJSON();\n\t\tjson.graveyardPosition = json.graveyardPosition.toJSON();\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"MergeOperation\";\n\t}\n\t/**\n\t* Creates `MergeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\tconst sourcePosition = ModelPosition.fromJSON(json.sourcePosition, document);\n\t\tconst targetPosition = ModelPosition.fromJSON(json.targetPosition, document);\n\t\tconst graveyardPosition = ModelPosition.fromJSON(json.graveyardPosition, document);\n\t\treturn new this(sourcePosition, json.howMany, targetPosition, graveyardPosition, json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/markeroperation\n*/\nvar MarkerOperation = class MarkerOperation extends Operation {\n\t/**\n\t* Marker name.\n\t*\n\t* @readonly\n\t*/\n\tname;\n\t/**\n\t* Marker range before the change.\n\t*\n\t* @readonly\n\t*/\n\toldRange;\n\t/**\n\t* Marker range after the change.\n\t*\n\t* @readonly\n\t*/\n\tnewRange;\n\t/**\n\t* Specifies whether the marker operation affects the data produced by the data pipeline\n\t* (is persisted in the editor's data).\n\t*\n\t* @readonly\n\t*/\n\taffectsData;\n\t/**\n\t* Marker collection on which change should be executed.\n\t*/\n\t_markers;\n\t/**\n\t* @param name Marker name.\n\t* @param oldRange Marker range before the change.\n\t* @param newRange Marker range after the change.\n\t* @param markers Marker collection on which change should be executed.\n\t* @param affectsData Specifies whether the marker operation affects the data produced by the data pipeline\n\t* (is persisted in the editor's data).\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(name, oldRange, newRange, markers, affectsData, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.name = name;\n\t\tthis.oldRange = oldRange ? oldRange.clone() : null;\n\t\tthis.newRange = newRange ? newRange.clone() : null;\n\t\tthis.affectsData = affectsData;\n\t\tthis._markers = markers;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\treturn \"marker\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\tconst ranges = [];\n\t\tif (this.oldRange) ranges.push(this.oldRange.clone());\n\t\tif (this.newRange) if (this.oldRange) ranges.push(...this.newRange.getDifference(this.oldRange));\n\t\telse ranges.push(this.newRange.clone());\n\t\treturn ranges;\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*/\n\tclone() {\n\t\treturn new MarkerOperation(this.name, this.oldRange, this.newRange, this._markers, this.affectsData, this.baseVersion);\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\treturn new MarkerOperation(this.name, this.newRange, this.oldRange, this._markers, this.affectsData, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\tif (this.newRange) this._markers._set(this.name, this.newRange, true, this.affectsData);\n\t\telse this._markers._remove(this.name);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tif (this.oldRange) json.oldRange = this.oldRange.toJSON();\n\t\tif (this.newRange) json.newRange = this.newRange.toJSON();\n\t\tdelete json._markers;\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"MarkerOperation\";\n\t}\n\t/**\n\t* Creates `MarkerOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\treturn new MarkerOperation(json.name, json.oldRange ? ModelRange.fromJSON(json.oldRange, document) : null, json.newRange ? ModelRange.fromJSON(json.newRange, document) : null, document.model.markers, json.affectsData, json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/attributeoperation\n*/\n/**\n* Operation to change nodes' attribute.\n*\n* Using this class you can add, remove or change value of the attribute.\n*/\nvar AttributeOperation = class AttributeOperation extends Operation {\n\t/**\n\t* Range on which operation should be applied.\n\t*\n\t* @readonly\n\t*/\n\trange;\n\t/**\n\t* Key of an attribute to change or remove.\n\t*\n\t* @readonly\n\t*/\n\tkey;\n\t/**\n\t* Old value of the attribute with given key or `null`, if attribute was not set before.\n\t*\n\t* @readonly\n\t*/\n\toldValue;\n\t/**\n\t* New value of the attribute with given key or `null`, if operation should remove attribute.\n\t*\n\t* @readonly\n\t*/\n\tnewValue;\n\t/**\n\t* Creates an operation that changes, removes or adds attributes.\n\t*\n\t* If only `newValue` is set, attribute will be added on a node. Note that all nodes in operation's range must not\n\t* have an attribute with the same key as the added attribute.\n\t*\n\t* If only `oldValue` is set, then attribute with given key will be removed. Note that all nodes in operation's range\n\t* must have an attribute with that key added.\n\t*\n\t* If both `newValue` and `oldValue` are set, then the operation will change the attribute value. Note that all nodes in\n\t* operation's ranges must already have an attribute with given key and `oldValue` as value\n\t*\n\t* @param range Range on which the operation should be applied. Must be a flat range.\n\t* @param key Key of an attribute to change or remove.\n\t* @param oldValue Old value of the attribute with given key or `null`, if attribute was not set before.\n\t* @param newValue New value of the attribute with given key or `null`, if operation should remove attribute.\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(range, key, oldValue, newValue, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.range = range.clone();\n\t\tthis.key = key;\n\t\tthis.oldValue = oldValue === void 0 ? null : oldValue;\n\t\tthis.newValue = newValue === void 0 ? null : newValue;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\tif (this.oldValue === null) return \"addAttribute\";\n\t\telse if (this.newValue === null) return \"removeAttribute\";\n\t\telse return \"changeAttribute\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\treturn this.range.clone();\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*/\n\tclone() {\n\t\treturn new AttributeOperation(this.range, this.key, this.oldValue, this.newValue, this.baseVersion);\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\treturn new AttributeOperation(this.range, this.key, this.newValue, this.oldValue, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.range = this.range.toJSON();\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_validate() {\n\t\tif (!this.range.isFlat)\n /**\n\t\t* The range to change is not flat.\n\t\t*\n\t\t* @error attribute-operation-range-not-flat\n\t\t*/\n\t\tthrow new CKEditorError(\"attribute-operation-range-not-flat\", this);\n\t\tfor (const item of this.range.getItems({ shallow: true })) {\n\t\t\tif (this.oldValue !== null && !isEqual(item.getAttribute(this.key), this.oldValue))\n /**\n\t\t\t* Changed node has different attribute value than operation's old attribute value.\n\t\t\t*\n\t\t\t* @error attribute-operation-wrong-old-value\n\t\t\t* @param {module:engine/model/item~ModelItem} root The item element.\n\t\t\t* @param {string} key The key of the attribute.\n\t\t\t* @param {never} value The value.\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"attribute-operation-wrong-old-value\", this, {\n\t\t\t\titem,\n\t\t\t\tkey: this.key,\n\t\t\t\tvalue: this.oldValue\n\t\t\t});\n\t\t\tif (this.oldValue === null && this.newValue !== null && item.hasAttribute(this.key))\n /**\n\t\t\t* The attribute with given key already exists for the given node.\n\t\t\t*\n\t\t\t* @error attribute-operation-attribute-exists\n\t\t\t* @param {module:engine/model/item~ModelItem} root The item element.\n\t\t\t* @param {string} key The key of the attribute.\n\t\t\t*/\n\t\t\tthrow new CKEditorError(\"attribute-operation-attribute-exists\", this, {\n\t\t\t\tnode: item,\n\t\t\t\tkey: this.key\n\t\t\t});\n\t\t}\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\tif (!isEqual(this.oldValue, this.newValue)) _setAttribute(this.range, this.key, this.newValue);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"AttributeOperation\";\n\t}\n\t/**\n\t* Creates `AttributeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\treturn new AttributeOperation(ModelRange.fromJSON(json.range, document), json.key, json.oldValue, json.newValue, json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/nooperation\n*/\n/**\n* Operation which is doing nothing (\"empty operation\", \"do-nothing operation\", \"noop\"). This is an operation,\n* which when executed does not change the tree model. It still has some parameters defined for transformation purposes.\n*\n* In most cases this operation is a result of transforming operations. When transformation returns\n* {@link module:engine/model/operation/nooperation~NoOperation} it means that changes done by the transformed operation\n* have already been applied.\n*/\nvar NoOperation = class NoOperation extends Operation {\n\tget type() {\n\t\treturn \"noop\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\treturn null;\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*/\n\tclone() {\n\t\treturn new NoOperation(this.baseVersion);\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\treturn new NoOperation(this.baseVersion + 1);\n\t}\n\t/** @internal */\n\t_execute() {}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"NoOperation\";\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/renameoperation\n*/\n/**\n* Operation to change element's name.\n*\n* Using this class you can change element's name.\n*/\nvar RenameOperation = class RenameOperation extends Operation {\n\t/**\n\t* Position before an element to change.\n\t*/\n\tposition;\n\t/**\n\t* Current name of the element.\n\t*/\n\toldName;\n\t/**\n\t* New name for the element.\n\t*/\n\tnewName;\n\t/**\n\t* Creates an operation that changes element's name.\n\t*\n\t* @param position Position before an element to change.\n\t* @param oldName Current name of the element.\n\t* @param newName New name for the element.\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(position, oldName, newName, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.position = position;\n\t\tthis.position.stickiness = \"toNext\";\n\t\tthis.oldName = oldName;\n\t\tthis.newName = newName;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\treturn \"rename\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\treturn this.position.nodeAfter;\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*\n\t* @returns Clone of this operation.\n\t*/\n\tclone() {\n\t\treturn new RenameOperation(this.position.clone(), this.oldName, this.newName, this.baseVersion);\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\treturn new RenameOperation(this.position.clone(), this.newName, this.oldName, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_validate() {\n\t\tconst element = this.position.nodeAfter;\n\t\tif (!(element instanceof ModelElement))\n /**\n\t\t* Given position is invalid or node after it is not instance of Element.\n\t\t*\n\t\t* @error rename-operation-wrong-position\n\t\t*/\n\t\tthrow new CKEditorError(\"rename-operation-wrong-position\", this);\n\t\telse if (this.oldName !== \"\" && element.name !== this.oldName)\n /**\n\t\t* Element to change has different name than operation's old name.\n\t\t*\n\t\t* @error rename-operation-wrong-name\n\t\t*/\n\t\tthrow new CKEditorError(\"rename-operation-wrong-name\", this);\n\t\tthis.oldName = element.name;\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\tconst element = this.position.nodeAfter;\n\t\telement.name = this.newName;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.position = this.position.toJSON();\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"RenameOperation\";\n\t}\n\t/**\n\t* Creates `RenameOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\treturn new RenameOperation(ModelPosition.fromJSON(json.position, document), json.oldName, json.newName, json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/rootattributeoperation\n*/\n/**\n* Operation to change root element's attribute. Using this class you can add, remove or change value of the attribute.\n*\n* This operation is needed, because root elements can't be changed through\n* {@link module:engine/model/operation/attributeoperation~AttributeOperation}.\n* It is because {@link module:engine/model/operation/attributeoperation~AttributeOperation}\n* requires a range to change and root element can't\n* be a part of range because every {@link module:engine/model/position~ModelPosition} has to be inside a root.\n* {@link module:engine/model/position~ModelPosition} can't be created before a root element.\n*/\nvar RootAttributeOperation = class RootAttributeOperation extends Operation {\n\t/**\n\t* Root element to change.\n\t*/\n\troot;\n\t/**\n\t* Key of an attribute to change or remove.\n\t*/\n\tkey;\n\t/**\n\t* Old value of the attribute with given key or `null`, if attribute was not set before.\n\t*\n\t* @readonly\n\t*/\n\toldValue;\n\t/**\n\t* New value of the attribute with given key or `null`, if operation should remove attribute.\n\t*\n\t* @readonly\n\t*/\n\tnewValue;\n\t/**\n\t* Creates an operation that changes, removes or adds attributes on root element.\n\t*\n\t* @see module:engine/model/operation/attributeoperation~AttributeOperation\n\t* @param root Root element to change.\n\t* @param key Key of an attribute to change or remove.\n\t* @param oldValue Old value of the attribute with given key or `null`, if attribute was not set before.\n\t* @param newValue New value of the attribute with given key or `null`, if operation should remove attribute.\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation\n\t* can be applied or `null` if the operation operates on detached (non-document) tree.\n\t*/\n\tconstructor(root, key, oldValue, newValue, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.root = root;\n\t\tthis.key = key;\n\t\tthis.oldValue = oldValue === void 0 ? null : oldValue;\n\t\tthis.newValue = newValue === void 0 ? null : newValue;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\tif (this.oldValue === null) return \"addRootAttribute\";\n\t\telse if (this.newValue === null) return \"removeRootAttribute\";\n\t\telse return \"changeRootAttribute\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\treturn this.root;\n\t}\n\t/**\n\t* Creates and returns an operation that has the same parameters as this operation.\n\t*\n\t* @returns Clone of this operation.\n\t*/\n\tclone() {\n\t\treturn new RootAttributeOperation(this.root, this.key, this.oldValue, this.newValue, this.baseVersion);\n\t}\n\t/**\n\t* See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t*/\n\tgetReversed() {\n\t\treturn new RootAttributeOperation(this.root, this.key, this.newValue, this.oldValue, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_validate() {\n\t\tif (this.root != this.root.root || this.root.is(\"documentFragment\"))\n /**\n\t\t* The element to change is not a root element.\n\t\t*\n\t\t* @error rootattribute-operation-not-a-root\n\t\t* @param {module:engine/model/rootelement~ModelRootElement} root The root element.\n\t\t* @param {string} key The key of the attribute.\n\t\t*/\n\t\tthrow new CKEditorError(\"rootattribute-operation-not-a-root\", this, {\n\t\t\troot: this.root,\n\t\t\tkey: this.key\n\t\t});\n\t\tif (this.oldValue !== null && !isEqual(this.root.getAttribute(this.key), this.oldValue))\n /**\n\t\t* The attribute which should be removed does not exist for the given node.\n\t\t*\n\t\t* @error rootattribute-operation-wrong-old-value\n\t\t* @param {module:engine/model/rootelement~ModelRootElement} root The root element.\n\t\t* @param {string} key The key of the attribute.\n\t\t*/\n\t\tthrow new CKEditorError(\"rootattribute-operation-wrong-old-value\", this, {\n\t\t\troot: this.root,\n\t\t\tkey: this.key\n\t\t});\n\t\tif (this.oldValue === null && this.newValue !== null && this.root.hasAttribute(this.key))\n /**\n\t\t* The attribute with given key already exists for the given node.\n\t\t*\n\t\t* @error rootattribute-operation-attribute-exists\n\t\t* @param {module:engine/model/rootelement~ModelRootElement} root The root element.\n\t\t* @param {string} key The key of the attribute.\n\t\t*/\n\t\tthrow new CKEditorError(\"rootattribute-operation-attribute-exists\", this, {\n\t\t\troot: this.root,\n\t\t\tkey: this.key\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\tif (this.newValue !== null) this.root._setAttribute(this.key, this.newValue);\n\t\telse this.root._removeAttribute(this.key);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.root = this.root.toJSON();\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"RootAttributeOperation\";\n\t}\n\t/**\n\t* Creates `RootAttributeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\tif (!document.getRoot(json.root))\n /**\n\t\t* Cannot create RootAttributeOperation for document. Root with the specified name does not exist.\n\t\t*\n\t\t* @error rootattribute-operation-fromjson-no-root\n\t\t* @param {string} rootName The root name.\n\t\t*/\n\t\tthrow new CKEditorError(\"rootattribute-operation-fromjson-no-root\", this, { rootName: json.root });\n\t\treturn new RootAttributeOperation(document.getRoot(json.root), json.key, json.oldValue, json.newValue, json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/rootoperation\n*/\n/**\n* Operation that creates (or attaches) or detaches a root element.\n*/\nvar RootOperation = class RootOperation extends Operation {\n\t/**\n\t* Root name to create or detach.\n\t*/\n\trootName;\n\t/**\n\t* Root element name.\n\t*/\n\telementName;\n\t/**\n\t* Specifies whether the operation adds (`true`) or detaches the root (`false`).\n\t*/\n\tisAdd;\n\t/**\n\t* Document which owns the root.\n\t*/\n\t_document;\n\t/**\n\t* Creates an operation that creates or removes a root element.\n\t*\n\t* @param rootName Root name to create or detach.\n\t* @param elementName Root element name.\n\t* @param isAdd Specifies whether the operation adds (`true`) or detaches the root (`false`).\n\t* @param document Document which owns the root.\n\t* @param baseVersion Document {@link module:engine/model/document~ModelDocument#version} on which operation can be applied.\n\t*/\n\tconstructor(rootName, elementName, isAdd, document, baseVersion) {\n\t\tsuper(baseVersion);\n\t\tthis.rootName = rootName;\n\t\tthis.elementName = elementName;\n\t\tthis.isAdd = isAdd;\n\t\tthis._document = document;\n\t\tif (!this._document.getRoot(this.rootName)) {\n\t\t\tconst root = this._document.createRoot(this.elementName, this.rootName);\n\t\t\troot._isAttached = false;\n\t\t}\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\treturn this.isAdd ? \"addRoot\" : \"detachRoot\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\treturn this._document.getRoot(this.rootName);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tclone() {\n\t\treturn new RootOperation(this.rootName, this.elementName, this.isAdd, this._document, this.baseVersion);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tgetReversed() {\n\t\treturn new RootOperation(this.rootName, this.elementName, !this.isAdd, this._document, this.baseVersion + 1);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\t_execute() {\n\t\tthis._document.getRoot(this.rootName)._isAttached = this.isAdd;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tdelete json._document;\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"RootOperation\";\n\t}\n\t/**\n\t* Creates `RootOperation` object from deserialized object, i.e. from parsed JSON string.\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\treturn new RootOperation(json.rootName, json.elementName, json.isAdd, document, json.baseVersion);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/operationfactory\n*/\nconst operations = {};\noperations[AttributeOperation.className] = AttributeOperation;\noperations[InsertOperation.className] = InsertOperation;\noperations[MarkerOperation.className] = MarkerOperation;\noperations[MoveOperation.className] = MoveOperation;\noperations[NoOperation.className] = NoOperation;\noperations[Operation.className] = Operation;\noperations[RenameOperation.className] = RenameOperation;\noperations[RootAttributeOperation.className] = RootAttributeOperation;\noperations[RootOperation.className] = RootOperation;\noperations[SplitOperation.className] = SplitOperation;\noperations[MergeOperation.className] = MergeOperation;\n/**\n* A factory class for creating operations.\n*/\nvar OperationFactory = class {\n\t/**\n\t* Creates an operation instance from a JSON object (parsed JSON string).\n\t*\n\t* @param json Deserialized JSON object.\n\t* @param document Document on which this operation will be applied.\n\t*/\n\tstatic fromJSON(json, document) {\n\t\treturn operations[json.__className].fromJSON(json, document);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/transform\n*/\nconst transformations = /* @__PURE__ */ new Map();\n/**\n* Sets a transformation function to be be used to transform instances of class `OperationA` by instances of class `OperationB`.\n*\n* The `transformationFunction` is passed three parameters:\n*\n* * `a` - operation to be transformed, an instance of `OperationA`,\n* * `b` - operation to be transformed by, an instance of `OperationB`,\n* * {@link module:engine/model/operation/transform~TransformationContext `context`} - object with additional information about\n* transformation context.\n*\n* The `transformationFunction` should return transformation result, which is an array with one or multiple\n* {@link module:engine/model/operation/operation~Operation operation} instances.\n*\n* @param transformationFunction Function to use for transforming.\n*/\nfunction setTransformation(OperationA, OperationB, transformationFunction) {\n\tlet aGroup = transformations.get(OperationA);\n\tif (!aGroup) {\n\t\taGroup = /* @__PURE__ */ new Map();\n\t\ttransformations.set(OperationA, aGroup);\n\t}\n\taGroup.set(OperationB, transformationFunction);\n}\n/**\n* Returns a previously set transformation function for transforming an instance of `OperationA` by an instance of `OperationB`.\n*\n* If no transformation was set for given pair of operations, {@link module:engine/model/operation/transform~noUpdateTransformation}\n* is returned. This means that if no transformation was set, the `OperationA` instance will not change when transformed\n* by the `OperationB` instance.\n*\n* @returns Function set to transform an instance of `OperationA` by an instance of `OperationB`.\n*/\nfunction getTransformation(OperationA, OperationB) {\n\tconst aGroup = transformations.get(OperationA);\n\tif (aGroup && aGroup.has(OperationB)) return aGroup.get(OperationB);\n\treturn noUpdateTransformation;\n}\n/**\n* A transformation function that only clones operation to transform, without changing it.\n*/\nfunction noUpdateTransformation(a) {\n\treturn [a];\n}\n/**\n* Transforms operation `a` by operation `b`.\n*\n* @param a Operation to be transformed.\n* @param b Operation to transform by.\n* @param context Transformation context for this transformation.\n* @returns Transformation result.\n* @internal\n*/\nfunction transform(a, b, context = {}) {\n\tconst transformationFunction = getTransformation(a.constructor, b.constructor);\n\ttry {\n\t\ta = a.clone();\n\t\treturn transformationFunction(a, b, context);\n\t} catch (e) {\n\t\tthrow e;\n\t}\n}\n/**\n* Performs a transformation of two sets of operations - `operationsA` and `operationsB`. The transformation is two-way -\n* both transformed `operationsA` and transformed `operationsB` are returned.\n*\n* Note, that the first operation in each set should base on the same document state (\n* {@link module:engine/model/document~ModelDocument#version document version}).\n*\n* It is assumed that `operationsA` are \"more important\" during conflict resolution between two operations.\n*\n* New copies of both passed arrays and operations inside them are returned. Passed arguments are not altered.\n*\n* Base versions of the transformed operations sets are updated accordingly. For example, assume that base versions are `4`\n* and there are `3` operations in `operationsA` and `5` operations in `operationsB`. Then:\n*\n* * transformed `operationsA` will start from base version `9` (`4` base version + `5` operations B),\n* * transformed `operationsB` will start from base version `7` (`4` base version + `3` operations A).\n*\n* If no operation was broken into two during transformation, then both sets will end up with an operation that bases on version `11`:\n*\n* * transformed `operationsA` start from `9` and there are `3` of them, so the last will have `baseVersion` equal to `11`,\n* * transformed `operationsB` start from `7` and there are `5` of them, so the last will have `baseVersion` equal to `11`.\n*\n* @param operationsA\n* @param operationsB\n* @param options Additional transformation options.\n* @param options.document Document which the operations change.\n* @param options.useRelations Whether during transformation relations should be used (used during undo for better conflict resolution).\n* @param options.padWithNoOps Whether additional {@link module:engine/model/operation/nooperation~NoOperation}s\n* should be added to the transformation results to force the same last base version for both transformed sets (in case\n* if some operations got broken into multiple operations during transformation).\n* @param options.forceWeakRemove If set to `false`, remove operation will be always stronger than move operation,\n* so the removed nodes won't end up back in the document root. When set to `true`, context data will be used.\n* @returns Transformation result.\n*/\nfunction transformOperationSets(operationsA, operationsB, options) {\n\toperationsA = operationsA.slice();\n\toperationsB = operationsB.slice();\n\tconst contextFactory = new ContextFactory(options.document, options.useRelations, options.forceWeakRemove);\n\tcontextFactory.setOriginalOperations(operationsA);\n\tcontextFactory.setOriginalOperations(operationsB);\n\tconst originalOperations = contextFactory.originalOperations;\n\tif (operationsA.length == 0 || operationsB.length == 0) return {\n\t\toperationsA,\n\t\toperationsB,\n\t\toriginalOperations\n\t};\n\tconst nextTransformIndex = /* @__PURE__ */ new WeakMap();\n\tfor (const op of operationsA) nextTransformIndex.set(op, 0);\n\tconst data = {\n\t\tnextBaseVersionA: operationsA[operationsA.length - 1].baseVersion + 1,\n\t\tnextBaseVersionB: operationsB[operationsB.length - 1].baseVersion + 1,\n\t\toriginalOperationsACount: operationsA.length,\n\t\toriginalOperationsBCount: operationsB.length\n\t};\n\tlet i = 0;\n\twhile (i < operationsA.length) {\n\t\tconst opA = operationsA[i];\n\t\tconst indexB = nextTransformIndex.get(opA);\n\t\tif (indexB == operationsB.length) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst opB = operationsB[indexB];\n\t\tconst newOpsA = transform(opA, opB, contextFactory.getContext(opA, opB, true));\n\t\tconst newOpsB = transform(opB, opA, contextFactory.getContext(opB, opA, false));\n\t\tcontextFactory.updateRelation(opA, opB);\n\t\tcontextFactory.setOriginalOperations(newOpsA, opA);\n\t\tcontextFactory.setOriginalOperations(newOpsB, opB);\n\t\tfor (const newOpA of newOpsA) nextTransformIndex.set(newOpA, indexB + newOpsB.length);\n\t\toperationsA.splice(i, 1, ...newOpsA);\n\t\toperationsB.splice(indexB, 1, ...newOpsB);\n\t}\n\thandlePartialMarkerOperations(operationsA);\n\thandlePartialMarkerOperations(operationsB);\n\tif (options.padWithNoOps) {\n\t\tconst brokenOperationsACount = operationsA.length - data.originalOperationsACount;\n\t\tconst brokenOperationsBCount = operationsB.length - data.originalOperationsBCount;\n\t\tpadWithNoOps(operationsA, brokenOperationsBCount - brokenOperationsACount);\n\t\tpadWithNoOps(operationsB, brokenOperationsACount - brokenOperationsBCount);\n\t}\n\tupdateBaseVersions(operationsA, data.nextBaseVersionB);\n\tupdateBaseVersions(operationsB, data.nextBaseVersionA);\n\treturn {\n\t\toperationsA,\n\t\toperationsB,\n\t\toriginalOperations\n\t};\n}\n/**\n* Gathers additional data about operations processed during transformation. Can be used to obtain contextual information\n* about two operations that are about to be transformed. This contextual information can be used for better conflict resolution.\n*/\nvar ContextFactory = class {\n\toriginalOperations;\n\t_history;\n\t_useRelations;\n\t_forceWeakRemove;\n\t_relations;\n\t/**\n\t* Creates `ContextFactory` instance.\n\t*\n\t* @param document Document which the operations change.\n\t* @param useRelations Whether during transformation relations should be used (used during undo for\n\t* better conflict resolution).\n\t* @param forceWeakRemove If set to `false`, remove operation will be always stronger than move operation,\n\t* so the removed nodes won't end up back in the document root. When set to `true`, context data will be used.\n\t*/\n\tconstructor(document, useRelations, forceWeakRemove = false) {\n\t\tthis.originalOperations = /* @__PURE__ */ new Map();\n\t\tthis._history = document.history;\n\t\tthis._useRelations = useRelations;\n\t\tthis._forceWeakRemove = !!forceWeakRemove;\n\t\tthis._relations = /* @__PURE__ */ new Map();\n\t}\n\t/**\n\t* Sets \"original operation\" for given operations.\n\t*\n\t* During transformation process, operations are cloned, then changed, then processed again, sometimes broken into two\n\t* or multiple operations. When gathering additional data it is important that all operations can be somehow linked\n\t* so a cloned and transformed \"version\" still kept track of the data assigned earlier to it.\n\t*\n\t* The original operation object will be used as such an universal linking id. Throughout the transformation process\n\t* all cloned operations will refer to \"the original operation\" when storing and reading additional data.\n\t*\n\t* If `takeFrom` is not set, each operation from `operations` array will be assigned itself as \"the original operation\".\n\t* This should be used as an initialization step.\n\t*\n\t* If `takeFrom` is set, each operation from `operations` will be assigned the same original operation as assigned\n\t* for `takeFrom` operation. This should be used to update original operations. It should be used in a way that\n\t* `operations` are the result of `takeFrom` transformation to ensure proper \"original operation propagation\".\n\t*/\n\tsetOriginalOperations(operations, takeFrom = null) {\n\t\tconst originalOperation = takeFrom ? this.originalOperations.get(takeFrom) : null;\n\t\tfor (const operation of operations) this.originalOperations.set(operation, originalOperation || operation);\n\t}\n\t/**\n\t* Saves a relation between operations `opA` and `opB`.\n\t*\n\t* Relations are then later used to help solve conflicts when operations are transformed.\n\t*/\n\tupdateRelation(opA, opB) {\n\t\tif (opA instanceof MoveOperation) {\n\t\t\tif (opB instanceof MergeOperation) {\n\t\t\t\tif (opA.targetPosition.isEqual(opB.sourcePosition) || opB.movedRange.containsPosition(opA.targetPosition)) this._setRelation(opA, opB, \"insertAtSource\");\n\t\t\t\telse if (opA.targetPosition.isEqual(opB.deletionPosition)) this._setRelation(opA, opB, \"insertBetween\");\n\t\t\t\telse if (opA.targetPosition.isAfter(opB.sourcePosition)) this._setRelation(opA, opB, \"moveTargetAfter\");\n\t\t\t\telse if (opA.howMany > 1 && opA.sourcePosition.isEqual(opB.deletionPosition)) this._setRelation(opA, opB, \"firstToMoveMerged\");\n\t\t\t\telse if (opA.howMany > 1 && opA.sourcePosition.getShiftedBy(opA.howMany - 1).isEqual(opB.deletionPosition)) this._setRelation(opA, opB, \"lastToMoveMerged\");\n\t\t\t} else if (opB instanceof MoveOperation) if (opA.targetPosition.isEqual(opB.sourcePosition) || opA.targetPosition.isBefore(opB.sourcePosition)) this._setRelation(opA, opB, \"insertBefore\");\n\t\t\telse this._setRelation(opA, opB, \"insertAfter\");\n\t\t} else if (opA instanceof SplitOperation) {\n\t\t\tif (opB instanceof MergeOperation) {\n\t\t\t\tif (opA.splitPosition.isBefore(opB.sourcePosition)) this._setRelation(opA, opB, \"splitBefore\");\n\t\t\t} else if (opB instanceof MoveOperation) if (opA.splitPosition.isEqual(opB.sourcePosition) || opA.splitPosition.isBefore(opB.sourcePosition)) this._setRelation(opA, opB, \"splitBefore\");\n\t\t\telse {\n\t\t\t\tconst range = ModelRange._createFromPositionAndShift(opB.sourcePosition, opB.howMany);\n\t\t\t\tif (opA.splitPosition.hasSameParentAs(opB.sourcePosition) && range.containsPosition(opA.splitPosition)) {\n\t\t\t\t\tconst howMany = range.end.offset - opA.splitPosition.offset;\n\t\t\t\t\tconst offset = opA.splitPosition.offset - range.start.offset;\n\t\t\t\t\tthis._setRelation(opA, opB, {\n\t\t\t\t\t\thowMany,\n\t\t\t\t\t\toffset\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (opA instanceof MergeOperation) {\n\t\t\tif (opB instanceof MergeOperation) {\n\t\t\t\tif (!opA.targetPosition.isEqual(opB.sourcePosition)) this._setRelation(opA, opB, \"mergeTargetNotMoved\");\n\t\t\t\tif (opA.sourcePosition.isEqual(opB.targetPosition)) this._setRelation(opA, opB, \"mergeSourceNotMoved\");\n\t\t\t\tif (opA.sourcePosition.isEqual(opB.sourcePosition)) this._setRelation(opA, opB, \"mergeSameElement\");\n\t\t\t} else if (opB instanceof SplitOperation) {\n\t\t\t\tif (opA.sourcePosition.isEqual(opB.splitPosition)) this._setRelation(opA, opB, \"splitAtSource\");\n\t\t\t} else if (opB instanceof MoveOperation && opB.howMany > 0) {\n\t\t\t\tif (opA.sourcePosition.isEqual(opB.sourcePosition.getShiftedBy(opB.howMany))) this._setRelation(opA, opB, \"mergeSourceAffected\");\n\t\t\t\tif (opA.targetPosition.isEqual(opB.sourcePosition)) this._setRelation(opA, opB, \"mergeTargetWasBefore\");\n\t\t\t}\n\t\t} else if (opA instanceof MarkerOperation) {\n\t\t\tconst markerRange = opA.newRange;\n\t\t\tif (!markerRange) return;\n\t\t\tif (opB instanceof MergeOperation) {\n\t\t\t\tconst wasInLeftElement = markerRange.start.isEqual(opB.targetPosition);\n\t\t\t\tconst wasStartBeforeMergedElement = markerRange.start.isEqual(opB.deletionPosition);\n\t\t\t\tconst wasEndBeforeMergedElement = markerRange.end.isEqual(opB.deletionPosition);\n\t\t\t\tconst wasInRightElement = markerRange.end.isEqual(opB.sourcePosition);\n\t\t\t\tif (wasInLeftElement || wasStartBeforeMergedElement || wasEndBeforeMergedElement || wasInRightElement) this._setRelation(opA, opB, {\n\t\t\t\t\twasInLeftElement,\n\t\t\t\t\twasStartBeforeMergedElement,\n\t\t\t\t\twasEndBeforeMergedElement,\n\t\t\t\t\twasInRightElement\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* Evaluates and returns contextual information about two given operations `opA` and `opB` which are about to be transformed.\n\t*/\n\tgetContext(opA, opB, aIsStrong) {\n\t\treturn {\n\t\t\taIsStrong,\n\t\t\taWasUndone: this._wasUndone(opA),\n\t\t\tbWasUndone: this._wasUndone(opB),\n\t\t\tabRelation: this._useRelations ? this._getRelation(opA, opB) : null,\n\t\t\tbaRelation: this._useRelations ? this._getRelation(opB, opA) : null,\n\t\t\tforceWeakRemove: this._forceWeakRemove\n\t\t};\n\t}\n\t/**\n\t* Returns whether given operation `op` has already been undone.\n\t*\n\t* Information whether an operation was undone gives more context when making a decision when two operations are in conflict.\n\t*/\n\t_wasUndone(op) {\n\t\tconst originalOp = this.originalOperations.get(op);\n\t\treturn originalOp.wasUndone || this._history.isUndoneOperation(originalOp);\n\t}\n\t/**\n\t* Returns a relation between `opA` and an operation which is undone by `opB`. This can be `String` value if a relation\n\t* was set earlier or `null` if there was no relation between those operations.\n\t*\n\t* This is a little tricky to understand, so let's compare it to `ContextFactory#_wasUndone`.\n\t*\n\t* When `wasUndone( opB )` is used, we check if the `opB` has already been undone. It is obvious, that the\n\t* undoing operation must happen after the undone operation. So, essentially, we have `opB`, we take document history,\n\t* we look forward in the future and ask if in that future `opB` was undone.\n\t*\n\t* Relations is a backward process to `wasUndone()`.\n\t*\n\t* Long story short - using relations is asking what happened in the past. Looking back. This time we have an undoing\n\t* operation `opB` which has undone some other operation. When there is a transformation `opA` x `opB` and there is\n\t* a conflict to solve and `opB` is an undoing operation, we can look back in the history and see what was a relation\n\t* between `opA` and the operation which `opB` undone. Basing on that relation from the past, we can now make\n\t* a better decision when resolving a conflict between two operations, because we know more about the context of\n\t* those two operations.\n\t*\n\t* This is why this function does not return a relation directly between `opA` and `opB` because we need to look\n\t* back to search for a meaningful contextual information.\n\t*/\n\t_getRelation(opA, opB) {\n\t\tconst origB = this.originalOperations.get(opB);\n\t\tconst undoneB = this._history.getUndoneOperation(origB);\n\t\tif (!undoneB) return null;\n\t\tconst origA = this.originalOperations.get(opA);\n\t\tconst relationsA = this._relations.get(origA);\n\t\tif (relationsA) return relationsA.get(undoneB) || null;\n\t\treturn null;\n\t}\n\t/**\n\t* Helper function for `ContextFactory#updateRelations`.\n\t*/\n\t_setRelation(opA, opB, relation) {\n\t\tconst origA = this.originalOperations.get(opA);\n\t\tconst origB = this.originalOperations.get(opB);\n\t\tlet relationsA = this._relations.get(origA);\n\t\tif (!relationsA) {\n\t\t\trelationsA = /* @__PURE__ */ new Map();\n\t\t\tthis._relations.set(origA, relationsA);\n\t\t}\n\t\trelationsA.set(origB, relation);\n\t}\n};\n/**\n* An utility function that updates {@link module:engine/model/operation/operation~Operation#baseVersion base versions}\n* of passed operations.\n*\n* The function simply sets `baseVersion` as a base version of the first passed operation and then increments it for\n* each following operation in `operations`.\n*\n* @param operations Operations to update.\n* @param baseVersion Base version to set for the first operation in `operations`.\n*/\nfunction updateBaseVersions(operations, baseVersion) {\n\tfor (const operation of operations) operation.baseVersion = baseVersion++;\n}\n/**\n* Adds `howMany` instances of {@link module:engine/model/operation/nooperation~NoOperation} to `operations` set.\n*/\nfunction padWithNoOps(operations, howMany) {\n\tfor (let i = 0; i < howMany; i++) operations.push(new NoOperation(0));\n}\n/**\n* Transformed operations set may include marker operations which were broken into multiple marker operations during transformation.\n* It represents marker range being broken into multiple pieces as the transformation was processed. Each partial marker operation is\n* a piece of the original marker range.\n*\n* These partial marker operations (\"marker range pieces\") should be \"glued\" together if, after transformations, the ranges ended up\n* next to each other.\n*\n* If the ranges did not end up next to each other, then partial marker operations should be discarded, as the marker range cannot\n* be broken into two pieces.\n*\n* There is always one \"reference\" marker operation (the original operation) and there may be some partial marker operations. Partial\n* marker operations have base version set to `-1`. If the `operations` set includes partial marker operations, then they are always\n* after the original marker operation.\n*\n* See also `MarkerOperation` x `MoveOperation` transformation.\n* See also https://github.com/ckeditor/ckeditor5/pull/17071.\n*/\nfunction handlePartialMarkerOperations(operations) {\n\tconst markerOps = /* @__PURE__ */ new Map();\n\tfor (let i = 0; i < operations.length; i++) {\n\t\tconst op = operations[i];\n\t\tif (!(op instanceof MarkerOperation)) continue;\n\t\tif (op.baseVersion !== -1) markerOps.set(op.name, {\n\t\t\top,\n\t\t\tranges: op.newRange ? [op.newRange] : []\n\t\t});\n\t\telse {\n\t\t\t/* v8 ignore next -- @preserve */\n\t\t\tif (op.newRange) {\n\t\t\t\tconst partialRanges = markerOps.get(op.name).ranges;\n\t\t\t\tif (!partialRanges[0].containsRange(op.newRange, true)) partialRanges.push(op.newRange);\n\t\t\t}\n\t\t\toperations.splice(i, 1);\n\t\t\ti--;\n\t\t}\n\t}\n\tfor (const { op, ranges } of markerOps.values()) if (ranges.length) op.newRange = ModelRange._createFromRanges(ranges);\n\telse op.newRange = null;\n}\nsetTransformation(AttributeOperation, AttributeOperation, (a, b, context) => {\n\tif (a.key === b.key && a.range.start.hasSameParentAs(b.range.start)) {\n\t\tconst operations = a.range.getDifference(b.range).map((range) => {\n\t\t\treturn new AttributeOperation(range, a.key, a.oldValue, a.newValue, 0);\n\t\t});\n\t\tconst common = a.range.getIntersection(b.range);\n\t\tif (common) {\n\t\t\tif (context.aIsStrong) operations.push(new AttributeOperation(common, b.key, b.newValue, a.newValue, 0));\n\t\t}\n\t\tif (operations.length == 0) return [new NoOperation(0)];\n\t\treturn operations;\n\t} else return [a];\n});\nsetTransformation(AttributeOperation, InsertOperation, (a, b) => {\n\tif (a.range.start.hasSameParentAs(b.position) && a.range.containsPosition(b.position)) {\n\t\tconst result = a.range._getTransformedByInsertion(b.position, b.howMany, !b.shouldReceiveAttributes).map((r) => {\n\t\t\treturn new AttributeOperation(r, a.key, a.oldValue, a.newValue, a.baseVersion);\n\t\t});\n\t\tif (b.shouldReceiveAttributes) {\n\t\t\tconst op = _getComplementaryAttributeOperations(b, a.key, a.oldValue);\n\t\t\tif (op) result.unshift(op);\n\t\t}\n\t\treturn result;\n\t}\n\ta.range = a.range._getTransformedByInsertion(b.position, b.howMany, false)[0];\n\treturn [a];\n});\n/**\n* Helper function for `AttributeOperation` x `InsertOperation` (and reverse) transformation.\n*\n* For given `insertOperation` it checks the inserted node if it has an attribute `key` set to a value different\n* than `newValue`. If so, it generates an `AttributeOperation` which changes the value of `key` attribute to `newValue`.\n*/\nfunction _getComplementaryAttributeOperations(insertOperation, key, newValue) {\n\tconst insertValue = insertOperation.nodes.getNode(0).getAttribute(key);\n\tif (insertValue == newValue) return null;\n\tconst range = new ModelRange(insertOperation.position, insertOperation.position.getShiftedBy(insertOperation.howMany));\n\treturn new AttributeOperation(range, key, insertValue, newValue, 0);\n}\nsetTransformation(AttributeOperation, MergeOperation, (a, b) => {\n\tconst ranges = [];\n\tif (a.range.start.hasSameParentAs(b.deletionPosition)) {\n\t\tif (a.range.containsPosition(b.deletionPosition) || a.range.start.isEqual(b.deletionPosition)) ranges.push(ModelRange._createFromPositionAndShift(b.graveyardPosition, 1));\n\t}\n\tconst range = a.range._getTransformedByMergeOperation(b);\n\tif (!range.isCollapsed) ranges.push(range);\n\treturn ranges.map((range) => {\n\t\treturn new AttributeOperation(range, a.key, a.oldValue, a.newValue, a.baseVersion);\n\t});\n});\nsetTransformation(AttributeOperation, MoveOperation, (a, b) => {\n\treturn _breakRangeByMoveOperation(a.range, b).map((range) => new AttributeOperation(range, a.key, a.oldValue, a.newValue, a.baseVersion));\n});\n/**\n* Helper function for `AttributeOperation` x `MoveOperation` transformation.\n*\n* Takes the passed `range` and transforms it by move operation `moveOp` in a specific way. Only top-level nodes of `range`\n* are considered to be in the range. If move operation moves nodes deep from inside of the range, those nodes won't\n* be included in the result. In other words, top-level nodes of the ranges from the result are exactly the same as\n* top-level nodes of the original `range`.\n*\n* This is important for `AttributeOperation` because, for its range, it changes only the top-level nodes. So we need to\n* track only how those nodes have been affected by `MoveOperation`.\n*/\nfunction _breakRangeByMoveOperation(range, moveOp) {\n\tconst moveRange = ModelRange._createFromPositionAndShift(moveOp.sourcePosition, moveOp.howMany);\n\tlet common = null;\n\tlet difference = [];\n\tif (moveRange.containsRange(range, true)) common = range;\n\telse if (range.start.hasSameParentAs(moveRange.start)) {\n\t\tdifference = range.getDifference(moveRange);\n\t\tcommon = range.getIntersection(moveRange);\n\t} else difference = [range];\n\tconst result = [];\n\tfor (let diff of difference) {\n\t\tdiff = diff._getTransformedByDeletion(moveOp.sourcePosition, moveOp.howMany);\n\t\tconst targetPosition = moveOp.getMovedRangeStart();\n\t\tconst spread = diff.start.hasSameParentAs(targetPosition);\n\t\tconst diffs = diff._getTransformedByInsertion(targetPosition, moveOp.howMany, spread);\n\t\tresult.push(...diffs);\n\t}\n\tif (common) result.push(common._getTransformedByMove(moveOp.sourcePosition, moveOp.targetPosition, moveOp.howMany, false)[0]);\n\treturn result;\n}\nsetTransformation(AttributeOperation, SplitOperation, (a, b) => {\n\tif (a.range.end.isEqual(b.insertionPosition)) {\n\t\tif (!b.graveyardPosition) a.range.end.offset++;\n\t\treturn [a];\n\t}\n\tif (a.range.start.hasSameParentAs(b.splitPosition) && a.range.containsPosition(b.splitPosition)) {\n\t\tconst secondPart = a.clone();\n\t\tsecondPart.range = new ModelRange(b.moveTargetPosition.clone(), a.range.end._getCombined(b.splitPosition, b.moveTargetPosition));\n\t\ta.range.end = b.splitPosition.clone();\n\t\ta.range.end.stickiness = \"toPrevious\";\n\t\treturn [a, secondPart];\n\t}\n\ta.range = a.range._getTransformedBySplitOperation(b);\n\treturn [a];\n});\nsetTransformation(InsertOperation, AttributeOperation, (a, b) => {\n\tconst result = [a];\n\tif (a.shouldReceiveAttributes && a.position.hasSameParentAs(b.range.start) && b.range.containsPosition(a.position)) {\n\t\tconst op = _getComplementaryAttributeOperations(a, b.key, b.newValue);\n\t\tif (op) result.push(op);\n\t}\n\treturn result;\n});\nsetTransformation(InsertOperation, InsertOperation, (a, b, context) => {\n\tif (a.position.isEqual(b.position) && context.aIsStrong) return [a];\n\ta.position = a.position._getTransformedByInsertOperation(b);\n\treturn [a];\n});\nsetTransformation(InsertOperation, MoveOperation, (a, b) => {\n\ta.position = a.position._getTransformedByMoveOperation(b);\n\treturn [a];\n});\nsetTransformation(InsertOperation, SplitOperation, (a, b) => {\n\ta.position = a.position._getTransformedBySplitOperation(b);\n\treturn [a];\n});\nsetTransformation(InsertOperation, MergeOperation, (a, b) => {\n\ta.position = a.position._getTransformedByMergeOperation(b);\n\treturn [a];\n});\nsetTransformation(MarkerOperation, InsertOperation, (a, b) => {\n\tif (a.oldRange) a.oldRange = a.oldRange._getTransformedByInsertOperation(b)[0];\n\tif (a.newRange) a.newRange = a.newRange._getTransformedByInsertOperation(b)[0];\n\treturn [a];\n});\nsetTransformation(MarkerOperation, MarkerOperation, (a, b, context) => {\n\tif (a.name == b.name) if (context.aIsStrong) a.oldRange = b.newRange ? b.newRange.clone() : null;\n\telse return [new NoOperation(0)];\n\treturn [a];\n});\nsetTransformation(MarkerOperation, MergeOperation, (a, b) => {\n\tif (a.oldRange) a.oldRange = a.oldRange._getTransformedByMergeOperation(b);\n\tif (a.newRange) a.newRange = a.newRange._getTransformedByMergeOperation(b);\n\treturn [a];\n});\nsetTransformation(MarkerOperation, MoveOperation, (a, b) => {\n\tconst result = [a];\n\tif (a.oldRange) a.oldRange = ModelRange._createFromRanges(a.oldRange._getTransformedByMoveOperation(b));\n\tif (a.newRange) {\n\t\tconst ranges = a.newRange._getTransformedByMoveOperation(b);\n\t\ta.newRange = ranges[0];\n\t\tfor (let i = 1; i < ranges.length; i++) {\n\t\t\tconst op = a.clone();\n\t\t\top.oldRange = null;\n\t\t\top.newRange = ranges[i];\n\t\t\top.baseVersion = -1;\n\t\t\tresult.push(op);\n\t\t}\n\t}\n\treturn result;\n});\nsetTransformation(MarkerOperation, SplitOperation, (a, b, context) => {\n\tif (a.oldRange) a.oldRange = a.oldRange._getTransformedBySplitOperation(b);\n\tif (a.newRange) {\n\t\tif (context.abRelation) {\n\t\t\tconst aNewRange = a.newRange._getTransformedBySplitOperation(b);\n\t\t\tif (a.newRange.start.isEqual(b.splitPosition)) if (context.abRelation.wasStartBeforeMergedElement) a.newRange.start = ModelPosition._createAt(b.insertionPosition);\n\t\t\telse if (context.abRelation.wasInLeftElement) a.newRange.start = ModelPosition._createAt(a.newRange.start);\n\t\t\telse a.newRange.start = ModelPosition._createAt(b.moveTargetPosition);\n\t\t\telse a.newRange.start = aNewRange.start;\n\t\t\tif (a.newRange.end.isEqual(b.splitPosition)) if (a.newRange.end.isEqual(b.splitPosition) && context.abRelation.wasEndBeforeMergedElement) a.newRange.end = ModelPosition._createAt(b.insertionPosition);\n\t\t\telse if (context.abRelation.wasInRightElement) a.newRange.end = ModelPosition._createAt(b.moveTargetPosition);\n\t\t\telse a.newRange.end = ModelPosition._createAt(a.newRange.end);\n\t\t\telse a.newRange.end = aNewRange.end;\n\t\t\treturn [a];\n\t\t}\n\t\ta.newRange = a.newRange._getTransformedBySplitOperation(b);\n\t}\n\treturn [a];\n});\nsetTransformation(MergeOperation, InsertOperation, (a, b) => {\n\tif (a.sourcePosition.hasSameParentAs(b.position)) a.howMany += b.howMany;\n\ta.sourcePosition = a.sourcePosition._getTransformedByInsertOperation(b);\n\ta.targetPosition = a.targetPosition._getTransformedByInsertOperation(b);\n\treturn [a];\n});\nsetTransformation(MergeOperation, MergeOperation, (a, b, context) => {\n\tif (a.sourcePosition.isEqual(b.sourcePosition) && a.targetPosition.isEqual(b.targetPosition)) if (!context.bWasUndone) return [new NoOperation(0)];\n\telse {\n\t\tconst path = b.graveyardPosition.path.slice();\n\t\tpath.push(0);\n\t\ta.sourcePosition = new ModelPosition(b.graveyardPosition.root, path);\n\t\ta.howMany = 0;\n\t\treturn [a];\n\t}\n\tif (a.sourcePosition.isEqual(b.sourcePosition) && !a.targetPosition.isEqual(b.targetPosition) && !context.bWasUndone && context.abRelation != \"splitAtSource\") {\n\t\tconst aToGraveyard = a.targetPosition.root.rootName == \"$graveyard\";\n\t\tconst bToGraveyard = b.targetPosition.root.rootName == \"$graveyard\";\n\t\tif (bToGraveyard && !aToGraveyard || !(aToGraveyard && !bToGraveyard) && context.aIsStrong) {\n\t\t\tconst sourcePosition = b.targetPosition._getTransformedByMergeOperation(b);\n\t\t\tconst targetPosition = a.targetPosition._getTransformedByMergeOperation(b);\n\t\t\treturn [new MoveOperation(sourcePosition, a.howMany, targetPosition, 0)];\n\t\t} else return [new NoOperation(0)];\n\t}\n\tif (a.sourcePosition.hasSameParentAs(b.targetPosition)) a.howMany += b.howMany;\n\ta.sourcePosition = a.sourcePosition._getTransformedByMergeOperation(b);\n\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation(b);\n\tif (!a.graveyardPosition.isEqual(b.graveyardPosition) || !context.aIsStrong) a.graveyardPosition = a.graveyardPosition._getTransformedByMergeOperation(b);\n\treturn [a];\n});\nsetTransformation(MergeOperation, MoveOperation, (a, b, context) => {\n\tconst removedRange = ModelRange._createFromPositionAndShift(b.sourcePosition, b.howMany);\n\tif (b.type == \"remove\" && !context.bWasUndone) {\n\t\tif (a.deletionPosition.hasSameParentAs(b.sourcePosition) && removedRange.containsPosition(a.sourcePosition)) return [new NoOperation(0)];\n\t}\n\tif (b.sourcePosition.getShiftedBy(b.howMany).isEqual(a.sourcePosition)) a.sourcePosition.stickiness = \"toNone\";\n\telse if (b.targetPosition.isEqual(a.sourcePosition) && context.abRelation == \"mergeSourceAffected\") a.sourcePosition.stickiness = \"toNext\";\n\telse if (b.sourcePosition.isEqual(a.targetPosition)) {\n\t\ta.targetPosition.stickiness = \"toNone\";\n\t\ta.howMany -= b.howMany;\n\t} else if (b.targetPosition.isEqual(a.targetPosition) && context.abRelation == \"mergeTargetWasBefore\") {\n\t\ta.targetPosition.stickiness = \"toPrevious\";\n\t\ta.howMany += b.howMany;\n\t} else {\n\t\tif (a.sourcePosition.hasSameParentAs(b.targetPosition)) a.howMany += b.howMany;\n\t\tif (a.sourcePosition.hasSameParentAs(b.sourcePosition)) a.howMany -= b.howMany;\n\t}\n\ta.sourcePosition = a.sourcePosition._getTransformedByMoveOperation(b);\n\ta.targetPosition = a.targetPosition._getTransformedByMoveOperation(b);\n\ta.sourcePosition.stickiness = \"toPrevious\";\n\ta.targetPosition.stickiness = \"toNext\";\n\tif (!a.graveyardPosition.isEqual(b.targetPosition)) a.graveyardPosition = a.graveyardPosition._getTransformedByMoveOperation(b);\n\treturn [a];\n});\nsetTransformation(MergeOperation, SplitOperation, (a, b, context) => {\n\tif (b.graveyardPosition) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByDeletion(b.graveyardPosition, 1);\n\t\tif (a.deletionPosition.isEqual(b.graveyardPosition)) a.howMany = b.howMany;\n\t}\n\tif (a.targetPosition.isEqual(b.splitPosition)) {\n\t\tif (b.graveyardPosition && a.deletionPosition.isEqual(b.graveyardPosition) || context.abRelation == \"mergeTargetNotMoved\") {\n\t\t\ta.sourcePosition = a.sourcePosition._getTransformedBySplitOperation(b);\n\t\t\treturn [a];\n\t\t}\n\t}\n\tif (a.sourcePosition.isEqual(b.splitPosition)) {\n\t\tif (context.abRelation == \"mergeSourceNotMoved\") {\n\t\t\ta.howMany = 0;\n\t\t\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation(b);\n\t\t\treturn [a];\n\t\t}\n\t\tif (context.abRelation == \"mergeSameElement\" || a.sourcePosition.offset > 0) {\n\t\t\ta.sourcePosition = b.moveTargetPosition.clone();\n\t\t\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation(b);\n\t\t\treturn [a];\n\t\t}\n\t}\n\tif (a.sourcePosition.hasSameParentAs(b.splitPosition)) a.howMany = b.splitPosition.offset;\n\ta.sourcePosition = a.sourcePosition._getTransformedBySplitOperation(b);\n\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation(b);\n\treturn [a];\n});\nsetTransformation(MoveOperation, InsertOperation, (a, b) => {\n\tconst transformed = ModelRange._createFromPositionAndShift(a.sourcePosition, a.howMany)._getTransformedByInsertOperation(b, false)[0];\n\ta.sourcePosition = transformed.start;\n\ta.howMany = transformed.end.offset - transformed.start.offset;\n\tif (!a.targetPosition.isEqual(b.position)) a.targetPosition = a.targetPosition._getTransformedByInsertOperation(b);\n\treturn [a];\n});\nsetTransformation(MoveOperation, MoveOperation, (a, b, context) => {\n\tconst rangeA = ModelRange._createFromPositionAndShift(a.sourcePosition, a.howMany);\n\tconst rangeB = ModelRange._createFromPositionAndShift(b.sourcePosition, b.howMany);\n\tlet aIsStrong = context.aIsStrong;\n\tlet insertBefore = !context.aIsStrong;\n\tif (context.abRelation == \"insertBefore\" || context.baRelation == \"insertAfter\") insertBefore = true;\n\telse if (context.abRelation == \"insertAfter\" || context.baRelation == \"insertBefore\") insertBefore = false;\n\tlet newTargetPosition;\n\tif (a.targetPosition.isEqual(b.targetPosition) && insertBefore) newTargetPosition = a.targetPosition._getTransformedByDeletion(b.sourcePosition, b.howMany);\n\telse newTargetPosition = a.targetPosition._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n\tif (_moveTargetIntoMovedRange(a, b) && _moveTargetIntoMovedRange(b, a)) return [b.getReversed()];\n\tif (rangeA.containsPosition(b.targetPosition) && rangeA.containsRange(rangeB, true)) {\n\t\trangeA.start = rangeA.start._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n\t\trangeA.end = rangeA.end._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n\t\treturn _makeMoveOperationsFromRanges([rangeA], newTargetPosition);\n\t}\n\tif (rangeB.containsPosition(a.targetPosition) && rangeB.containsRange(rangeA, true)) {\n\t\trangeA.start = rangeA.start._getCombined(b.sourcePosition, b.getMovedRangeStart());\n\t\trangeA.end = rangeA.end._getCombined(b.sourcePosition, b.getMovedRangeStart());\n\t\treturn _makeMoveOperationsFromRanges([rangeA], newTargetPosition);\n\t}\n\tconst aCompB = compareArrays(a.sourcePosition.getParentPath(), b.sourcePosition.getParentPath());\n\tif (aCompB == \"prefix\" || aCompB == \"extension\") {\n\t\trangeA.start = rangeA.start._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n\t\trangeA.end = rangeA.end._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n\t\treturn _makeMoveOperationsFromRanges([rangeA], newTargetPosition);\n\t}\n\tif (a.type == \"remove\" && b.type != \"remove\" && !context.aWasUndone && !context.forceWeakRemove) aIsStrong = true;\n\telse if (a.type != \"remove\" && b.type == \"remove\" && !context.bWasUndone && !context.forceWeakRemove) aIsStrong = false;\n\tconst ranges = [];\n\tconst difference = rangeA.getDifference(rangeB);\n\tfor (const range of difference) {\n\t\trange.start = range.start._getTransformedByDeletion(b.sourcePosition, b.howMany);\n\t\trange.end = range.end._getTransformedByDeletion(b.sourcePosition, b.howMany);\n\t\tconst shouldSpread = compareArrays(range.start.getParentPath(), b.getMovedRangeStart().getParentPath()) == \"same\";\n\t\tconst newRanges = range._getTransformedByInsertion(b.getMovedRangeStart(), b.howMany, shouldSpread);\n\t\tranges.push(...newRanges);\n\t}\n\tconst common = rangeA.getIntersection(rangeB);\n\tif (common !== null && aIsStrong) {\n\t\tcommon.start = common.start._getCombined(b.sourcePosition, b.getMovedRangeStart());\n\t\tcommon.end = common.end._getCombined(b.sourcePosition, b.getMovedRangeStart());\n\t\tif (ranges.length === 0) ranges.push(common);\n\t\telse if (ranges.length == 1) if (rangeB.start.isBefore(rangeA.start) || rangeB.start.isEqual(rangeA.start)) ranges.unshift(common);\n\t\telse ranges.push(common);\n\t\telse ranges.splice(1, 0, common);\n\t}\n\tif (ranges.length === 0) return [new NoOperation(a.baseVersion)];\n\treturn _makeMoveOperationsFromRanges(ranges, newTargetPosition);\n});\nsetTransformation(MoveOperation, SplitOperation, (a, b, context) => {\n\tlet newTargetPosition = a.targetPosition.clone();\n\tif (!a.targetPosition.isEqual(b.insertionPosition) || !b.graveyardPosition || context.abRelation == \"moveTargetAfter\") newTargetPosition = a.targetPosition._getTransformedBySplitOperation(b);\n\tif (a.sourcePosition.isEqual(b.insertionPosition) && context.abRelation == \"firstToMoveMerged\") {\n\t\ta.howMany++;\n\t\ta.targetPosition = newTargetPosition;\n\t\treturn [a];\n\t}\n\tconst moveRange = ModelRange._createFromPositionAndShift(a.sourcePosition, a.howMany);\n\tif (moveRange.end.isEqual(b.insertionPosition)) {\n\t\tif (!b.graveyardPosition || context.abRelation == \"lastToMoveMerged\") a.howMany++;\n\t\ta.targetPosition = newTargetPosition;\n\t\treturn [a];\n\t}\n\tif (moveRange.start.hasSameParentAs(b.splitPosition) && moveRange.containsPosition(b.splitPosition)) {\n\t\tlet rightRange = new ModelRange(b.splitPosition, moveRange.end);\n\t\trightRange = rightRange._getTransformedBySplitOperation(b);\n\t\treturn _makeMoveOperationsFromRanges([new ModelRange(moveRange.start, b.splitPosition), rightRange], newTargetPosition);\n\t}\n\tif (a.targetPosition.isEqual(b.splitPosition) && context.abRelation == \"insertAtSource\") newTargetPosition = b.moveTargetPosition;\n\tif (a.targetPosition.isEqual(b.insertionPosition) && context.abRelation == \"insertBetween\") newTargetPosition = a.targetPosition;\n\tconst ranges = [moveRange._getTransformedBySplitOperation(b)];\n\tif (b.graveyardPosition) {\n\t\tconst movesGraveyardElement = moveRange.start.isEqual(b.graveyardPosition) || moveRange.containsPosition(b.graveyardPosition);\n\t\tif (a.howMany > 1 && movesGraveyardElement && !context.aWasUndone) ranges.push(ModelRange._createFromPositionAndShift(b.insertionPosition, 1));\n\t}\n\treturn _makeMoveOperationsFromRanges(ranges, newTargetPosition);\n});\nsetTransformation(MoveOperation, MergeOperation, (a, b, context) => {\n\tconst movedRange = ModelRange._createFromPositionAndShift(a.sourcePosition, a.howMany);\n\tif (b.deletionPosition.hasSameParentAs(a.sourcePosition) && movedRange.containsPosition(b.sourcePosition)) {\n\t\tif (a.type == \"remove\" && !context.forceWeakRemove) {\n\t\t\tif (!context.aWasUndone) {\n\t\t\t\tconst results = [];\n\t\t\t\tlet gyMoveSource = b.graveyardPosition.clone();\n\t\t\t\tlet splitNodesMoveSource = b.targetPosition._getTransformedByMergeOperation(b);\n\t\t\t\tconst aTarget = a.targetPosition.getTransformedByOperation(b);\n\t\t\t\tif (a.howMany > 1) {\n\t\t\t\t\tresults.push(new MoveOperation(a.sourcePosition, a.howMany - 1, aTarget, 0));\n\t\t\t\t\tgyMoveSource = gyMoveSource._getTransformedByMove(a.sourcePosition, aTarget, a.howMany - 1);\n\t\t\t\t\tsplitNodesMoveSource = splitNodesMoveSource._getTransformedByMove(a.sourcePosition, aTarget, a.howMany - 1);\n\t\t\t\t}\n\t\t\t\tconst gyMoveTarget = b.deletionPosition._getCombined(a.sourcePosition, aTarget);\n\t\t\t\tconst gyMove = new MoveOperation(gyMoveSource, 1, gyMoveTarget, 0);\n\t\t\t\tconst splitNodesMoveTargetPath = gyMove.getMovedRangeStart().path.slice();\n\t\t\t\tsplitNodesMoveTargetPath.push(0);\n\t\t\t\tconst splitNodesMoveTarget = new ModelPosition(gyMove.targetPosition.root, splitNodesMoveTargetPath);\n\t\t\t\tsplitNodesMoveSource = splitNodesMoveSource._getTransformedByMove(gyMoveSource, gyMoveTarget, 1);\n\t\t\t\tconst splitNodesMove = new MoveOperation(splitNodesMoveSource, b.howMany, splitNodesMoveTarget, 0);\n\t\t\t\tresults.push(gyMove);\n\t\t\t\tresults.push(splitNodesMove);\n\t\t\t\treturn results;\n\t\t\t}\n\t\t} else if (a.howMany == 1) if (!context.bWasUndone) return [new NoOperation(0)];\n\t\telse {\n\t\t\ta.sourcePosition = b.graveyardPosition.clone();\n\t\t\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation(b);\n\t\t\treturn [a];\n\t\t}\n\t}\n\tconst transformed = ModelRange._createFromPositionAndShift(a.sourcePosition, a.howMany)._getTransformedByMergeOperation(b);\n\ta.sourcePosition = transformed.start;\n\ta.howMany = transformed.end.offset - transformed.start.offset;\n\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation(b);\n\treturn [a];\n});\nsetTransformation(RenameOperation, InsertOperation, (a, b) => {\n\ta.position = a.position._getTransformedByInsertOperation(b);\n\treturn [a];\n});\nsetTransformation(RenameOperation, MergeOperation, (a, b) => {\n\tif (a.position.isEqual(b.deletionPosition)) {\n\t\ta.position = b.graveyardPosition.clone();\n\t\ta.position.stickiness = \"toNext\";\n\t\treturn [a];\n\t}\n\ta.position = a.position._getTransformedByMergeOperation(b);\n\treturn [a];\n});\nsetTransformation(RenameOperation, MoveOperation, (a, b) => {\n\ta.position = a.position._getTransformedByMoveOperation(b);\n\treturn [a];\n});\nsetTransformation(RenameOperation, RenameOperation, (a, b, context) => {\n\tif (a.position.isEqual(b.position)) if (context.aIsStrong) a.oldName = b.newName;\n\telse return [new NoOperation(0)];\n\treturn [a];\n});\nsetTransformation(RenameOperation, SplitOperation, (a, b) => {\n\tconst renamePath = a.position.path;\n\tconst splitPath = b.splitPosition.getParentPath();\n\tif (compareArrays(renamePath, splitPath) == \"same\" && !b.graveyardPosition) return [a, new RenameOperation(a.position.getShiftedBy(1), a.oldName, a.newName, 0)];\n\ta.position = a.position._getTransformedBySplitOperation(b);\n\treturn [a];\n});\nsetTransformation(RootAttributeOperation, RootAttributeOperation, (a, b, context) => {\n\tif (a.root === b.root && a.key === b.key) if (!context.aIsStrong) return [new NoOperation(0)];\n\telse a.oldValue = b.newValue;\n\treturn [a];\n});\nsetTransformation(RootOperation, RootOperation, (a, b) => {\n\tif (a.rootName === b.rootName && a.isAdd === b.isAdd) return [new NoOperation(0)];\n\treturn [a];\n});\nsetTransformation(SplitOperation, InsertOperation, (a, b) => {\n\tif (a.splitPosition.hasSameParentAs(b.position) && a.splitPosition.offset < b.position.offset) a.howMany += b.howMany;\n\ta.splitPosition = a.splitPosition._getTransformedByInsertOperation(b);\n\ta.insertionPosition = a.insertionPosition._getTransformedByInsertOperation(b);\n\treturn [a];\n});\nsetTransformation(SplitOperation, MergeOperation, (a, b, context) => {\n\tif (!a.graveyardPosition && !context.bWasUndone && a.splitPosition.hasSameParentAs(b.sourcePosition)) {\n\t\tconst splitPath = b.graveyardPosition.path.slice();\n\t\tsplitPath.push(0);\n\t\tconst splitPosition = new ModelPosition(b.graveyardPosition.root, splitPath);\n\t\tconst insertionPosition = SplitOperation.getInsertionPosition(new ModelPosition(b.graveyardPosition.root, splitPath));\n\t\tconst additionalSplit = new SplitOperation(splitPosition, 0, insertionPosition, null, 0);\n\t\ta.splitPosition = a.splitPosition._getTransformedByMergeOperation(b);\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n\t\ta.graveyardPosition = additionalSplit.insertionPosition.clone();\n\t\ta.graveyardPosition.stickiness = \"toNext\";\n\t\treturn [additionalSplit, a];\n\t}\n\tif (a.splitPosition.hasSameParentAs(b.deletionPosition) && !a.splitPosition.isAfter(b.deletionPosition)) a.howMany--;\n\tif (a.splitPosition.hasSameParentAs(b.targetPosition)) a.howMany += b.howMany;\n\ta.splitPosition = a.splitPosition._getTransformedByMergeOperation(b);\n\ta.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n\tif (a.graveyardPosition) a.graveyardPosition = a.graveyardPosition._getTransformedByMergeOperation(b);\n\treturn [a];\n});\nsetTransformation(SplitOperation, MoveOperation, (a, b, context) => {\n\tconst rangeToMove = ModelRange._createFromPositionAndShift(b.sourcePosition, b.howMany);\n\tif (a.graveyardPosition) {\n\t\tconst gyElementMoved = rangeToMove.start.isEqual(a.graveyardPosition) || rangeToMove.containsPosition(a.graveyardPosition);\n\t\tif (!context.bWasUndone && gyElementMoved) {\n\t\t\tconst sourcePosition = a.splitPosition._getTransformedByMoveOperation(b);\n\t\t\tconst newParentPosition = a.graveyardPosition._getTransformedByMoveOperation(b);\n\t\t\tconst newTargetPath = newParentPosition.path.slice();\n\t\t\tnewTargetPath.push(0);\n\t\t\tconst newTargetPosition = new ModelPosition(newParentPosition.root, newTargetPath);\n\t\t\treturn [new MoveOperation(sourcePosition, a.howMany, newTargetPosition, 0)];\n\t\t}\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMoveOperation(b);\n\t}\n\tconst splitAtTarget = a.splitPosition.isEqual(b.targetPosition);\n\tif (splitAtTarget && (context.baRelation == \"insertAtSource\" || context.abRelation == \"splitBefore\")) {\n\t\ta.howMany += b.howMany;\n\t\ta.splitPosition = a.splitPosition._getTransformedByDeletion(b.sourcePosition, b.howMany);\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n\t\treturn [a];\n\t}\n\tif (splitAtTarget && context.abRelation && context.abRelation.howMany) {\n\t\tconst { howMany, offset } = context.abRelation;\n\t\ta.howMany += howMany;\n\t\ta.splitPosition = a.splitPosition.getShiftedBy(offset);\n\t\treturn [a];\n\t}\n\tif (a.splitPosition.hasSameParentAs(b.sourcePosition) && rangeToMove.containsPosition(a.splitPosition)) {\n\t\tconst howManyRemoved = b.howMany - (a.splitPosition.offset - b.sourcePosition.offset);\n\t\ta.howMany -= howManyRemoved;\n\t\tif (a.splitPosition.hasSameParentAs(b.targetPosition) && a.splitPosition.offset < b.targetPosition.offset) a.howMany += b.howMany;\n\t\ta.splitPosition = b.sourcePosition.clone();\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n\t\treturn [a];\n\t}\n\tif (!b.sourcePosition.isEqual(b.targetPosition)) {\n\t\tif (a.splitPosition.hasSameParentAs(b.sourcePosition) && a.splitPosition.offset <= b.sourcePosition.offset) a.howMany -= b.howMany;\n\t\tif (a.splitPosition.hasSameParentAs(b.targetPosition) && a.splitPosition.offset < b.targetPosition.offset) a.howMany += b.howMany;\n\t}\n\ta.splitPosition.stickiness = \"toNone\";\n\ta.splitPosition = a.splitPosition._getTransformedByMoveOperation(b);\n\ta.splitPosition.stickiness = \"toNext\";\n\tif (a.graveyardPosition) a.insertionPosition = a.insertionPosition._getTransformedByMoveOperation(b);\n\telse a.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n\treturn [a];\n});\nsetTransformation(SplitOperation, SplitOperation, (a, b, context) => {\n\tif (a.splitPosition.isEqual(b.splitPosition)) {\n\t\tif (!a.graveyardPosition && !b.graveyardPosition) return [new NoOperation(0)];\n\t\tif (a.graveyardPosition && b.graveyardPosition && a.graveyardPosition.isEqual(b.graveyardPosition)) return [new NoOperation(0)];\n\t\tif (context.abRelation == \"splitBefore\") {\n\t\t\ta.howMany = 0;\n\t\t\ta.graveyardPosition = a.graveyardPosition._getTransformedBySplitOperation(b);\n\t\t\treturn [a];\n\t\t}\n\t}\n\tif (a.graveyardPosition && b.graveyardPosition && a.graveyardPosition.isEqual(b.graveyardPosition)) {\n\t\tconst aInGraveyard = a.splitPosition.root.rootName == \"$graveyard\";\n\t\tconst bInGraveyard = b.splitPosition.root.rootName == \"$graveyard\";\n\t\tif (bInGraveyard && !aInGraveyard || !(aInGraveyard && !bInGraveyard) && context.aIsStrong) {\n\t\t\tconst result = [];\n\t\t\tif (b.howMany) result.push(new MoveOperation(b.moveTargetPosition, b.howMany, b.splitPosition, 0));\n\t\t\tif (a.howMany) result.push(new MoveOperation(a.splitPosition, a.howMany, a.moveTargetPosition, 0));\n\t\t\treturn result;\n\t\t} else return [new NoOperation(0)];\n\t}\n\tif (a.graveyardPosition) a.graveyardPosition = a.graveyardPosition._getTransformedBySplitOperation(b);\n\tif (a.splitPosition.isEqual(b.insertionPosition) && context.abRelation == \"splitBefore\") {\n\t\ta.howMany++;\n\t\treturn [a];\n\t}\n\tif (b.splitPosition.isEqual(a.insertionPosition) && context.baRelation == \"splitBefore\") {\n\t\tconst newPositionPath = b.insertionPosition.path.slice();\n\t\tnewPositionPath.push(0);\n\t\tconst newPosition = new ModelPosition(b.insertionPosition.root, newPositionPath);\n\t\treturn [a, new MoveOperation(a.insertionPosition, 1, newPosition, 0)];\n\t}\n\tif (a.splitPosition.hasSameParentAs(b.splitPosition) && a.splitPosition.offset < b.splitPosition.offset) a.howMany -= b.howMany;\n\ta.splitPosition = a.splitPosition._getTransformedBySplitOperation(b);\n\ta.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n\treturn [a];\n});\n/**\n* Checks whether `MoveOperation` `targetPosition` is inside a node from the moved range of the other `MoveOperation`.\n*/\nfunction _moveTargetIntoMovedRange(a, b) {\n\treturn a.targetPosition._getTransformedByDeletion(b.sourcePosition, b.howMany) === null;\n}\n/**\n* Helper function for `MoveOperation` x `MoveOperation` transformation. Converts given ranges and target position to\n* move operations and returns them.\n*\n* Ranges and target position will be transformed on-the-fly when generating operations.\n*\n* Given `ranges` should be in the order of how they were in the original transformed operation.\n*\n* Given `targetPosition` is the target position of the first range from `ranges`.\n*/\nfunction _makeMoveOperationsFromRanges(ranges, targetPosition) {\n\tconst operations = [];\n\tfor (let i = 0; i < ranges.length; i++) {\n\t\tconst range = ranges[i];\n\t\tconst op = new MoveOperation(range.start, range.end.offset - range.start.offset, targetPosition, 0);\n\t\toperations.push(op);\n\t\tfor (let j = i + 1; j < ranges.length; j++) ranges[j] = ranges[j]._getTransformedByMove(op.sourcePosition, op.targetPosition, op.howMany)[0];\n\t\ttargetPosition = targetPosition._getTransformedByMove(op.sourcePosition, op.targetPosition, op.howMany);\n\t}\n\treturn operations;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/liveposition\n*/\nconst ModelLivePositionBase = /* #__PURE__ */ EmitterMixin(ModelPosition);\n/**\n* `ModelLivePosition` is a type of {@link module:engine/model/position~ModelPosition Position}\n* that updates itself as {@link module:engine/model/document~ModelDocument document}\n* is changed through operations. It may be used as a bookmark.\n*\n* **Note:** Contrary to {@link module:engine/model/position~ModelPosition}, `ModelLivePosition` works only in roots that are\n* {@link module:engine/model/rootelement~ModelRootElement}.\n* If {@link module:engine/model/documentfragment~ModelDocumentFragment} is passed, error will be thrown.\n*\n* **Note:** Be very careful when dealing with `ModelLivePosition`. Each `ModelLivePosition` instance bind events that might\n* have to be unbound.\n* Use {@link module:engine/model/liveposition~ModelLivePosition#detach} whenever you don't need `ModelLivePosition` anymore.\n*/\nvar ModelLivePosition = class extends ModelLivePositionBase {\n\t/**\n\t* Creates a live position.\n\t*\n\t* @see module:engine/model/position~ModelPosition\n\t*/\n\tconstructor(root, path, stickiness = \"toNone\", model) {\n\t\tsuper(root, path, stickiness);\n\t\tconst boundModel = model || (this.root.is(\"rootElement\") ? this.root.document.model : null);\n\t\tif (!boundModel)\n /**\n\t\t* LivePosition's root has to be an instance of ModelRootElement or have a reference to a model instance.\n\t\t*\n\t\t* @error model-liveposition-no-model-reference\n\t\t*/\n\t\tthrow new CKEditorError(\"model-liveposition-no-model-reference\", root);\n\t\tbindWithModel.call(this, boundModel);\n\t}\n\t/**\n\t* Unbinds all events previously bound by `ModelLivePosition`. Use it whenever you don't need `ModelLivePosition` instance\n\t* anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was\n\t* referring to it).\n\t*/\n\tdetach() {\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Creates a {@link module:engine/model/position~ModelPosition position instance}, which is equal to this live position.\n\t*/\n\ttoPosition() {\n\t\treturn new ModelPosition(this.root, this.path.slice(), this.stickiness);\n\t}\n\t/**\n\t* Creates a `ModelLivePosition` instance that is equal to position.\n\t*/\n\tstatic fromPosition(position, stickiness) {\n\t\treturn new this(position.root, position.path.slice(), stickiness ? stickiness : position.stickiness);\n\t}\n\t/**\n\t* Creates a `ModelLivePosition` for a position rooted in\n\t* a {@link module:engine/model/documentfragment~ModelDocumentFragment document fragment}.\n\t*\n\t* Document fragment does not belong to a document, so the live position is bound to the provided `model` and keeps\n\t* itself in sync with every operation applied to that fragment (e.g. while editing clipboard content).\n\t*\n\t* @internal\n\t*/\n\tstatic _fromPositionInDocumentFragment(position, model, stickiness) {\n\t\treturn new this(position.root, position.path.slice(), stickiness ? stickiness : position.stickiness, model);\n\t}\n};\nModelLivePosition.prototype.is = function(type) {\n\treturn type === \"livePosition\" || type === \"model:livePosition\" || type == \"position\" || type === \"model:position\";\n};\n/**\n* Binds this `ModelLivePosition` to the given model, so the position updates itself on every operation applied to it.\n*/\nfunction bindWithModel(model) {\n\tconst isDetached = !this.root.is(\"rootElement\");\n\tthis.listenTo(model, \"applyOperation\", (event, args) => {\n\t\tconst operation = args[0];\n\t\tif (!isDetached && !operation.isDocumentOperation) return;\n\t\ttransform$1.call(this, operation);\n\t}, { priority: \"low\" });\n}\n/**\n* Updates this position accordingly to the updates applied to the model. Bases on change events.\n*/\nfunction transform$1(operation) {\n\tconst result = this.getTransformedByOperation(operation);\n\tif (!this.isEqual(result)) {\n\t\tconst oldPosition = this.toPosition();\n\t\tthis.path = result.path;\n\t\tthis.root = result.root;\n\t\tthis.fire(\"change\", oldPosition);\n\t}\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/batch\n*/\n/**\n* A batch instance groups model changes ({@link module:engine/model/operation/operation~Operation operations}). All operations\n* grouped in a single batch can be reverted together, so you can also think about a batch as of a single undo step. If you want\n* to extend a given undo step, you can add more changes to the batch using {@link module:engine/model/model~Model#enqueueChange}:\n*\n* ```ts\n* model.enqueueChange( batch, writer => {\n* \twriter.insertText( 'foo', paragraph, 'end' );\n* } );\n* ```\n*\n* @see module:engine/model/model~Model#enqueueChange\n* @see module:engine/model/model~Model#change\n*/\nvar Batch = class {\n\t/**\n\t* An array of operations that compose this batch.\n\t*/\n\toperations;\n\t/**\n\t* Whether the batch can be undone through the undo feature.\n\t*/\n\tisUndoable;\n\t/**\n\t* Whether the batch includes operations created locally (`true`) or operations created on other, remote editors (`false`).\n\t*/\n\tisLocal;\n\t/**\n\t* Whether the batch was created by the undo feature and undoes other operations.\n\t*/\n\tisUndo;\n\t/**\n\t* Whether the batch includes operations connected with typing.\n\t*/\n\tisTyping;\n\t/**\n\t* Creates a batch instance.\n\t*\n\t* @see module:engine/model/model~Model#enqueueChange\n\t* @see module:engine/model/model~Model#change\n\t* @param type A set of flags that specify the type of the batch. Batch type can alter how some of the features work\n\t* when encountering a given `Batch` instance (for example, when a feature listens to applied operations).\n\t*/\n\tconstructor(type = {}) {\n\t\tif (typeof type === \"string\") {\n\t\t\ttype = type === \"transparent\" ? { isUndoable: false } : {};\n\t\t\t/**\n\t\t\t* The string value for a `type` property of the `Batch` constructor has been deprecated and will be removed in the near future.\n\t\t\t* Please refer to the {@link module:engine/model/batch~Batch#constructor `Batch` constructor API documentation} for more\n\t\t\t* information.\n\t\t\t*\n\t\t\t* @error batch-constructor-deprecated-string-type\n\t\t\t*/\n\t\t\tlogWarning(\"batch-constructor-deprecated-string-type\");\n\t\t}\n\t\tconst { isUndoable = true, isLocal = true, isUndo = false, isTyping = false } = type;\n\t\tthis.operations = [];\n\t\tthis.isUndoable = isUndoable;\n\t\tthis.isLocal = isLocal;\n\t\tthis.isUndo = isUndo;\n\t\tthis.isTyping = isTyping;\n\t}\n\t/**\n\t* Returns the base version of this batch, which is equal to the base version of the first operation in the batch.\n\t* If there are no operations in the batch or neither operation has the base version set, it returns `null`.\n\t*/\n\tget baseVersion() {\n\t\tfor (const op of this.operations) if (op.baseVersion !== null) return op.baseVersion;\n\t\treturn null;\n\t}\n\t/**\n\t* Adds an operation to the batch instance.\n\t*\n\t* @param operation An operation to add.\n\t* @returns The added operation.\n\t*/\n\taddOperation(operation) {\n\t\tif (operation.isDocumentOperation) {\n\t\t\toperation.batch = this;\n\t\t\tthis.operations.push(operation);\n\t\t}\n\t\treturn operation;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/differ\n*/\n/**\n* Calculates the difference between two model states.\n*\n* Receives operations that are to be applied on the model document. Marks parts of the model document tree which\n* are changed and saves the state of these elements before the change. Then, it compares saved elements with the\n* changed elements, after all changes are applied on the model document. Calculates the diff between saved\n* elements and new ones and returns a change set.\n*/\nvar Differ = class Differ {\n\t/**\n\t* Priority of the {@link ~Differ#_elementState element states}. States on higher indexes of the array can overwrite states on the lower\n\t* indexes.\n\t*/\n\tstatic _statesPriority = [\n\t\tvoid 0,\n\t\t\"refresh\",\n\t\t\"rename\",\n\t\t\"move\"\n\t];\n\t/**\n\t* Reference to the model's marker collection.\n\t*/\n\t_markerCollection;\n\t/**\n\t* A map that stores changes that happened in a given element.\n\t*\n\t* The keys of the map are references to the model elements.\n\t* The values of the map are arrays with changes that were done on this element.\n\t*/\n\t_changesInElement = /* @__PURE__ */ new Map();\n\t/**\n\t* Stores a snapshot for these model nodes that might have changed.\n\t*\n\t* This complements {@link ~Differ#_elementChildrenSnapshots `_elementChildrenSnapshots`}.\n\t*\n\t* See also {@link ~DifferSnapshot}.\n\t*/\n\t_elementsSnapshots = /* @__PURE__ */ new Map();\n\t/**\n\t* For each element or document fragment inside which there was a change, it stores a snapshot of the child nodes list (an array\n\t* of children snapshots that represent the state in the element / fragment before any change has happened).\n\t*\n\t* This complements {@link ~Differ#_elementsSnapshots `_elementsSnapshots`}.\n\t*\n\t* See also {@link ~DifferSnapshot}.\n\t*/\n\t_elementChildrenSnapshots = /* @__PURE__ */ new Map();\n\t/**\n\t* Keeps the state for a given element, describing how the element was changed so far. It is used to evaluate the `action` property\n\t* of diff items returned by {@link ~Differ#getChanges}.\n\t*\n\t* Possible values, in the order from the lowest priority to the highest priority:\n\t*\n\t* * `'refresh'` - element was refreshed,\n\t* * `'rename'` - element was renamed,\n\t* * `'move'` - element was moved (or, usually, removed, that is moved to the graveyard).\n\t*\n\t* Element that was refreshed, may change its state to `'rename'` if it was later renamed, or to `'move'` if it was removed.\n\t* But the element cannot change its state from `'move'` to `'rename'`, or from `'rename'` to `'refresh'`.\n\t*\n\t* Only already existing elements are registered in `_elementState`. If a new element was inserted as a result of a buffered operation,\n\t* it is not be registered in `_elementState`.\n\t*/\n\t_elementState = /* @__PURE__ */ new Map();\n\t/**\n\t* A map that stores all changed markers.\n\t*\n\t* The keys of the map are marker names.\n\t*\n\t* The values of the map are objects with the following properties:\n\t*\n\t* * `oldMarkerData`,\n\t* * `newMarkerData`.\n\t*/\n\t_changedMarkers = /* @__PURE__ */ new Map();\n\t/**\n\t* A map that stores all roots that have been changed.\n\t*\n\t* The keys are the names of the roots while value represents the changes.\n\t*/\n\t_changedRoots = /* @__PURE__ */ new Map();\n\t/**\n\t* Stores the number of changes that were processed. Used to order the changes chronologically. It is important\n\t* when changes are sorted.\n\t*/\n\t_changeCount = 0;\n\t/**\n\t* For efficiency purposes, `Differ` stores the change set returned by the differ after {@link #getChanges} call.\n\t* Cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t* return the cached value instead of calculating it again.\n\t*\n\t* This property stores those changes that did not take place in graveyard root.\n\t*/\n\t_cachedChanges = null;\n\t/**\n\t* For efficiency purposes, `Differ` stores the change set returned by the differ after the {@link #getChanges} call.\n\t* The cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t* return the cached value instead of calculating it again.\n\t*\n\t* This property stores all changes evaluated by `Differ`, including those that took place in the graveyard.\n\t*/\n\t_cachedChangesWithGraveyard = null;\n\t/**\n\t* Set of model items that were marked to get refreshed in {@link #_refreshItem}.\n\t*/\n\t_refreshedItems = /* @__PURE__ */ new Set();\n\t/**\n\t* Creates a `Differ` instance.\n\t*\n\t* @param markerCollection Model's marker collection.\n\t*/\n\tconstructor(markerCollection) {\n\t\tthis._markerCollection = markerCollection;\n\t}\n\t/**\n\t* Informs whether there are any changes buffered in `Differ`.\n\t*/\n\tget isEmpty() {\n\t\treturn this._changesInElement.size == 0 && this._changedMarkers.size == 0 && this._changedRoots.size == 0;\n\t}\n\t/**\n\t* Buffers the given operation. **An operation has to be buffered before it is executed.**\n\t*\n\t* @param operationToBuffer An operation to buffer.\n\t*/\n\tbufferOperation(operationToBuffer) {\n\t\tconst operation = operationToBuffer;\n\t\tswitch (operation.type) {\n\t\t\tcase \"insert\":\n\t\t\t\tif (this._isInInsertedElement(operation.position.parent)) return;\n\t\t\t\tthis._markInsert(operation.position.parent, operation.position.offset, operation.nodes.maxOffset);\n\t\t\t\tbreak;\n\t\t\tcase \"addAttribute\":\n\t\t\tcase \"removeAttribute\":\n\t\t\tcase \"changeAttribute\":\n\t\t\t\tfor (const item of operation.range.getItems({ shallow: true })) {\n\t\t\t\t\tif (this._isInInsertedElement(item.parent)) continue;\n\t\t\t\t\tthis._markAttribute(item);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"remove\":\n\t\t\tcase \"move\":\n\t\t\tcase \"reinsert\": {\n\t\t\t\tif (operation.sourcePosition.isEqual(operation.targetPosition) || operation.sourcePosition.getShiftedBy(operation.howMany).isEqual(operation.targetPosition)) return;\n\t\t\t\tconst sourceParentInserted = this._isInInsertedElement(operation.sourcePosition.parent);\n\t\t\t\tconst targetParentInserted = this._isInInsertedElement(operation.targetPosition.parent);\n\t\t\t\tif (!sourceParentInserted) this._markRemove(operation.sourcePosition.parent, operation.sourcePosition.offset, operation.howMany);\n\t\t\t\tif (!targetParentInserted) this._markInsert(operation.targetPosition.parent, operation.getMovedRangeStart().offset, operation.howMany);\n\t\t\t\tconst range = ModelRange._createFromPositionAndShift(operation.sourcePosition, operation.howMany);\n\t\t\t\tfor (const node of range.getItems({ shallow: true })) this._setElementState(node, \"move\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"rename\": {\n\t\t\t\tif (this._isInInsertedElement(operation.position.parent)) return;\n\t\t\t\tthis._markRemove(operation.position.parent, operation.position.offset, 1);\n\t\t\t\tthis._markInsert(operation.position.parent, operation.position.offset, 1);\n\t\t\t\tconst range = ModelRange._createFromPositionAndShift(operation.position, 1);\n\t\t\t\tfor (const marker of this._markerCollection.getMarkersIntersectingRange(range)) {\n\t\t\t\t\tconst markerData = marker.getData();\n\t\t\t\t\tthis.bufferMarkerChange(marker.name, markerData, markerData);\n\t\t\t\t}\n\t\t\t\tthis._setElementState(operation.position.nodeAfter, \"rename\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"split\": {\n\t\t\t\tconst splitElement = operation.splitPosition.parent;\n\t\t\t\tif (!this._isInInsertedElement(splitElement)) {\n\t\t\t\t\tthis._markRemove(splitElement, operation.splitPosition.offset, operation.howMany);\n\t\t\t\t\tconst range = ModelRange._createFromPositionAndShift(operation.splitPosition, operation.howMany);\n\t\t\t\t\tfor (const node of range.getItems({ shallow: true })) this._setElementState(node, \"move\");\n\t\t\t\t}\n\t\t\t\tif (!this._isInInsertedElement(operation.insertionPosition.parent)) this._markInsert(operation.insertionPosition.parent, operation.insertionPosition.offset, 1);\n\t\t\t\tif (operation.graveyardPosition) {\n\t\t\t\t\tthis._markRemove(operation.graveyardPosition.parent, operation.graveyardPosition.offset, 1);\n\t\t\t\t\tthis._setElementState(operation.graveyardPosition.nodeAfter, \"move\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"merge\": {\n\t\t\t\tconst mergedElement = operation.sourcePosition.parent;\n\t\t\t\tif (!this._isInInsertedElement(mergedElement.parent)) this._markRemove(mergedElement.parent, mergedElement.startOffset, 1);\n\t\t\t\tconst graveyardParent = operation.graveyardPosition.parent;\n\t\t\t\tthis._markInsert(graveyardParent, operation.graveyardPosition.offset, 1);\n\t\t\t\tthis._setElementState(mergedElement, \"move\");\n\t\t\t\tconst mergedIntoElement = operation.targetPosition.parent;\n\t\t\t\tif (!this._isInInsertedElement(mergedIntoElement)) {\n\t\t\t\t\tthis._markInsert(mergedIntoElement, operation.targetPosition.offset, mergedElement.maxOffset);\n\t\t\t\t\tconst range = ModelRange._createFromPositionAndShift(operation.sourcePosition, operation.howMany);\n\t\t\t\t\tfor (const node of range.getItems({ shallow: true })) this._setElementState(node, \"move\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"detachRoot\":\n\t\t\tcase \"addRoot\": {\n\t\t\t\tconst root = operation.affectedSelectable;\n\t\t\t\tif (!root._isLoaded) return;\n\t\t\t\tif (root.isAttached() == operation.isAdd) return;\n\t\t\t\tthis._bufferRootStateChange(operation.rootName, operation.isAdd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"addRootAttribute\":\n\t\t\tcase \"removeRootAttribute\":\n\t\t\tcase \"changeRootAttribute\": {\n\t\t\t\tif (!operation.root._isLoaded) return;\n\t\t\t\tconst rootName = operation.root.rootName;\n\t\t\t\tthis._bufferRootAttributeChange(rootName, operation.key, operation.oldValue, operation.newValue);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tthis._cachedChanges = null;\n\t}\n\t/**\n\t* Buffers a marker change.\n\t*\n\t* @param markerName The name of the marker that changed.\n\t* @param oldMarkerData Marker data before the change.\n\t* @param newMarkerData Marker data after the change.\n\t*/\n\tbufferMarkerChange(markerName, oldMarkerData, newMarkerData) {\n\t\tif (oldMarkerData.range && oldMarkerData.range.root.is(\"rootElement\") && !oldMarkerData.range.root._isLoaded) oldMarkerData.range = null;\n\t\tif (newMarkerData.range && newMarkerData.range.root.is(\"rootElement\") && !newMarkerData.range.root._isLoaded) newMarkerData.range = null;\n\t\tlet buffered = this._changedMarkers.get(markerName);\n\t\tif (!buffered) {\n\t\t\tbuffered = {\n\t\t\t\tnewMarkerData,\n\t\t\t\toldMarkerData\n\t\t\t};\n\t\t\tthis._changedMarkers.set(markerName, buffered);\n\t\t} else buffered.newMarkerData = newMarkerData;\n\t\tif (buffered.oldMarkerData.range == null && newMarkerData.range == null) this._changedMarkers.delete(markerName);\n\t}\n\t/**\n\t* Returns all markers that should be removed as a result of buffered changes.\n\t*\n\t* @returns Markers to remove. Each array item is an object containing the `name` and `range` properties.\n\t*/\n\tgetMarkersToRemove() {\n\t\tconst result = [];\n\t\tfor (const [name, change] of this._changedMarkers) if (change.oldMarkerData.range != null) result.push({\n\t\t\tname,\n\t\t\trange: change.oldMarkerData.range\n\t\t});\n\t\treturn result;\n\t}\n\t/**\n\t* Returns all markers which should be added as a result of buffered changes.\n\t*\n\t* @returns Markers to add. Each array item is an object containing the `name` and `range` properties.\n\t*/\n\tgetMarkersToAdd() {\n\t\tconst result = [];\n\t\tfor (const [name, change] of this._changedMarkers) if (change.newMarkerData.range != null) result.push({\n\t\t\tname,\n\t\t\trange: change.newMarkerData.range\n\t\t});\n\t\treturn result;\n\t}\n\t/**\n\t* Returns all markers which changed.\n\t*/\n\tgetChangedMarkers() {\n\t\treturn Array.from(this._changedMarkers).map(([name, change]) => ({\n\t\t\tname,\n\t\t\tdata: {\n\t\t\t\toldRange: change.oldMarkerData.range,\n\t\t\t\tnewRange: change.newMarkerData.range\n\t\t\t}\n\t\t}));\n\t}\n\t/**\n\t* Checks whether some of the buffered changes affect the editor data.\n\t*\n\t* Types of changes which affect the editor data:\n\t*\n\t* * model structure changes,\n\t* * attribute changes,\n\t* * a root is added or detached,\n\t* * changes of markers which were defined as `affectsData`,\n\t* * changes of markers' `affectsData` property.\n\t*/\n\thasDataChanges() {\n\t\tif (this.getChanges().length) return true;\n\t\tif (this._changedRoots.size > 0) return true;\n\t\tfor (const { newMarkerData, oldMarkerData } of this._changedMarkers.values()) {\n\t\t\tif (newMarkerData.affectsData !== oldMarkerData.affectsData) return true;\n\t\t\tif (newMarkerData.affectsData) {\n\t\t\t\tconst markerAdded = newMarkerData.range && !oldMarkerData.range;\n\t\t\t\tconst markerRemoved = !newMarkerData.range && oldMarkerData.range;\n\t\t\t\tconst markerChanged = newMarkerData.range && oldMarkerData.range && !newMarkerData.range.isEqual(oldMarkerData.range);\n\t\t\t\tif (markerAdded || markerRemoved || markerChanged) return true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\t/**\n\t* Calculates the diff between the old model tree state (the state before the first buffered operations since the last {@link #reset}\n\t* call) and the new model tree state (actual one). It should be called after all buffered operations are executed.\n\t*\n\t* The diff set is returned as an array of {@link module:engine/model/differ~DifferItem diff items}, each describing a change done\n\t* on the model. The items are sorted by the position on which the change happened. If a position\n\t* {@link module:engine/model/position~ModelPosition#isBefore is before} another one, it will be on an earlier index in the diff set.\n\t*\n\t* **Note**: Elements inside inserted element will not have a separate diff item, only the top most element change will be reported.\n\t*\n\t* Because calculating the diff is a costly operation, the result is cached. If no new operation was buffered since the\n\t* previous {@link #getChanges} call, the next call will return the cached value.\n\t*\n\t* @param options Additional options.\n\t* @param options.includeChangesInGraveyard If set to `true`, also changes that happened\n\t* in the graveyard root will be returned. By default, changes in the graveyard root are not returned.\n\t* @returns Diff between the old and the new model tree state.\n\t*/\n\tgetChanges(options = {}) {\n\t\tif (this._cachedChanges) if (options.includeChangesInGraveyard) return this._cachedChangesWithGraveyard.slice();\n\t\telse return this._cachedChanges.slice();\n\t\tlet diffSet = [];\n\t\tfor (const element of this._changesInElement.keys()) {\n\t\t\tconst changes = this._changesInElement.get(element).sort((a, b) => {\n\t\t\t\tif (a.offset === b.offset) {\n\t\t\t\t\tif (a.type != b.type) return a.type == \"remove\" ? -1 : 1;\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\treturn a.offset < b.offset ? -1 : 1;\n\t\t\t});\n\t\t\tconst childrenBefore = this._elementChildrenSnapshots.get(element);\n\t\t\tconst childrenAfter = _getChildrenSnapshots(element.getChildren());\n\t\t\tconst diffInstructions = _generateDiffInstructionsFromChanges(childrenBefore.length, changes);\n\t\t\tlet i = 0;\n\t\t\tlet j = 0;\n\t\t\tfor (const instruction of diffInstructions) if (instruction === \"i\") {\n\t\t\t\tconst action = this._getDiffActionForNode(childrenAfter[i].node, \"insert\");\n\t\t\t\tconst childSnapshotBefore = this._elementsSnapshots.get(childrenAfter[i].node);\n\t\t\t\tconst diffItem = this._getInsertDiff(element, i, action, childrenAfter[i], childSnapshotBefore);\n\t\t\t\tdiffSet.push(diffItem);\n\t\t\t\ti++;\n\t\t\t} else if (instruction === \"r\") {\n\t\t\t\tconst action = this._getDiffActionForNode(childrenBefore[j].node, \"remove\");\n\t\t\t\tconst diffItem = this._getRemoveDiff(element, i, action, childrenBefore[j]);\n\t\t\t\tdiffSet.push(diffItem);\n\t\t\t\tj++;\n\t\t\t} else if (instruction === \"a\") {\n\t\t\t\tconst beforeAttributes = childrenBefore[j].attributes;\n\t\t\t\tconst afterAttributes = childrenAfter[i].attributes;\n\t\t\t\tlet range;\n\t\t\t\tif (childrenAfter[i].name == \"$text\") range = new ModelRange(ModelPosition._createAt(element, i), ModelPosition._createAt(element, i + 1));\n\t\t\t\telse {\n\t\t\t\t\tconst index = element.offsetToIndex(i);\n\t\t\t\t\trange = new ModelRange(ModelPosition._createAt(element, i), ModelPosition._createAt(element.getChild(index), 0));\n\t\t\t\t}\n\t\t\t\tconst diffItems = this._getAttributesDiff(range, beforeAttributes, afterAttributes);\n\t\t\t\tdiffSet.push(...diffItems);\n\t\t\t\ti++;\n\t\t\t\tj++;\n\t\t\t} else {\n\t\t\t\ti++;\n\t\t\t\tj++;\n\t\t\t}\n\t\t}\n\t\tdiffSet.sort((a, b) => {\n\t\t\tif (a.position.root != b.position.root) return a.position.root.rootName < b.position.root.rootName ? -1 : 1;\n\t\t\tif (a.position.isEqual(b.position)) return a.changeCount - b.changeCount;\n\t\t\treturn a.position.isBefore(b.position) ? -1 : 1;\n\t\t});\n\t\tfor (let i = 1, prevIndex = 0; i < diffSet.length; i++) {\n\t\t\tconst prevDiff = diffSet[prevIndex];\n\t\t\tconst thisDiff = diffSet[i];\n\t\t\tconst isConsecutiveTextRemove = prevDiff.type == \"remove\" && thisDiff.type == \"remove\" && prevDiff.name == \"$text\" && thisDiff.name == \"$text\" && prevDiff.position.isEqual(thisDiff.position);\n\t\t\tconst isConsecutiveTextAdd = prevDiff.type == \"insert\" && thisDiff.type == \"insert\" && prevDiff.name == \"$text\" && thisDiff.name == \"$text\" && prevDiff.position.parent == thisDiff.position.parent && prevDiff.position.offset + prevDiff.length == thisDiff.position.offset;\n\t\t\tconst isConsecutiveAttributeChange = prevDiff.type == \"attribute\" && thisDiff.type == \"attribute\" && prevDiff.position.parent == thisDiff.position.parent && prevDiff.range.isFlat && thisDiff.range.isFlat && prevDiff.position.offset + prevDiff.length == thisDiff.position.offset && prevDiff.attributeKey == thisDiff.attributeKey && prevDiff.attributeOldValue == thisDiff.attributeOldValue && prevDiff.attributeNewValue == thisDiff.attributeNewValue;\n\t\t\tif (isConsecutiveTextRemove || isConsecutiveTextAdd || isConsecutiveAttributeChange) {\n\t\t\t\tprevDiff.length++;\n\t\t\t\tif (isConsecutiveAttributeChange) prevDiff.range.end = prevDiff.range.end.getShiftedBy(1);\n\t\t\t\tdiffSet[i] = null;\n\t\t\t} else prevIndex = i;\n\t\t}\n\t\tdiffSet = diffSet.filter((v) => v);\n\t\tfor (const item of diffSet) {\n\t\t\tdelete item.changeCount;\n\t\t\tif (item.type == \"attribute\") {\n\t\t\t\tdelete item.position;\n\t\t\t\tdelete item.length;\n\t\t\t}\n\t\t}\n\t\tthis._changeCount = 0;\n\t\tthis._cachedChangesWithGraveyard = diffSet;\n\t\tthis._cachedChanges = diffSet.filter(_changesInGraveyardFilter);\n\t\tif (options.includeChangesInGraveyard) return this._cachedChangesWithGraveyard.slice();\n\t\telse return this._cachedChanges.slice();\n\t}\n\t/**\n\t* Returns all roots that have changed (either were attached, or detached, or their attributes changed).\n\t*\n\t* @returns Diff between the old and the new roots state.\n\t*/\n\tgetChangedRoots() {\n\t\treturn Array.from(this._changedRoots.values()).map((diffItem) => {\n\t\t\tconst entry = { ...diffItem };\n\t\t\tif (entry.state !== void 0) delete entry.attributes;\n\t\t\treturn entry;\n\t\t});\n\t}\n\t/**\n\t* Returns a set of model items that were marked to get refreshed.\n\t*/\n\tgetRefreshedItems() {\n\t\treturn new Set(this._refreshedItems);\n\t}\n\t/**\n\t* Resets `Differ`. Removes all buffered changes.\n\t*/\n\treset() {\n\t\tthis._changesInElement.clear();\n\t\tthis._elementChildrenSnapshots.clear();\n\t\tthis._elementsSnapshots.clear();\n\t\tthis._elementState.clear();\n\t\tthis._changedMarkers.clear();\n\t\tthis._changedRoots.clear();\n\t\tthis._refreshedItems.clear();\n\t\tthis._cachedChanges = null;\n\t}\n\t/**\n\t* Marks the given `item` in differ to be \"refreshed\". It means that the item will be marked as removed and inserted\n\t* in the differ changes set, so it will be effectively re-converted when the differ changes are handled by a dispatcher.\n\t*\n\t* @internal\n\t* @param item Item to refresh.\n\t*/\n\t_refreshItem(item) {\n\t\tif (this._isInInsertedElement(item.parent)) return;\n\t\tthis._markRemove(item.parent, item.startOffset, item.offsetSize);\n\t\tthis._markInsert(item.parent, item.startOffset, item.offsetSize);\n\t\tthis._refreshedItems.add(item);\n\t\tthis._setElementState(item, \"refresh\");\n\t\tconst range = ModelRange._createOn(item);\n\t\tfor (const marker of this._markerCollection.getMarkersIntersectingRange(range)) {\n\t\t\tconst markerData = marker.getData();\n\t\t\tthis.bufferMarkerChange(marker.name, markerData, markerData);\n\t\t}\n\t\tthis._cachedChanges = null;\n\t}\n\t/**\n\t* Buffers all the data related to given root like it was all just added to the editor.\n\t*\n\t* Following changes are buffered:\n\t*\n\t* * root is attached,\n\t* * all root content is inserted,\n\t* * all root attributes are added,\n\t* * all markers inside the root are added.\n\t*\n\t* @internal\n\t*/\n\t_bufferRootLoad(root) {\n\t\tif (!root.isAttached()) return;\n\t\tthis._bufferRootStateChange(root.rootName, true);\n\t\tthis._markInsert(root, 0, root.maxOffset);\n\t\tfor (const key of root.getAttributeKeys()) this._bufferRootAttributeChange(root.rootName, key, null, root.getAttribute(key));\n\t\tfor (const marker of this._markerCollection) if (marker.getRange().root == root) {\n\t\t\tconst markerData = marker.getData();\n\t\t\tthis.bufferMarkerChange(marker.name, {\n\t\t\t\t...markerData,\n\t\t\t\trange: null\n\t\t\t}, markerData);\n\t\t}\n\t}\n\t/**\n\t* Buffers the root state change after the root was attached or detached\n\t*/\n\t_bufferRootStateChange(rootName, isAttached) {\n\t\tif (!this._changedRoots.has(rootName)) {\n\t\t\tthis._changedRoots.set(rootName, {\n\t\t\t\tname: rootName,\n\t\t\t\tstate: isAttached ? \"attached\" : \"detached\"\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst diffItem = this._changedRoots.get(rootName);\n\t\tif (diffItem.state !== void 0) {\n\t\t\tdelete diffItem.state;\n\t\t\tif (diffItem.attributes === void 0) this._changedRoots.delete(rootName);\n\t\t} else diffItem.state = isAttached ? \"attached\" : \"detached\";\n\t}\n\t/**\n\t* Buffers a root attribute change.\n\t*/\n\t_bufferRootAttributeChange(rootName, key, oldValue, newValue) {\n\t\tconst diffItem = this._changedRoots.get(rootName) || { name: rootName };\n\t\tconst attrs = diffItem.attributes || {};\n\t\tif (attrs[key]) {\n\t\t\tconst attrEntry = attrs[key];\n\t\t\tif (newValue === attrEntry.oldValue) delete attrs[key];\n\t\t\telse attrEntry.newValue = newValue;\n\t\t} else attrs[key] = {\n\t\t\toldValue,\n\t\t\tnewValue\n\t\t};\n\t\tif (Object.entries(attrs).length === 0) {\n\t\t\tdelete diffItem.attributes;\n\t\t\tif (diffItem.state === void 0) this._changedRoots.delete(rootName);\n\t\t} else {\n\t\t\tdiffItem.attributes = attrs;\n\t\t\tthis._changedRoots.set(rootName, diffItem);\n\t\t}\n\t}\n\t/**\n\t* Saves and handles an insert change.\n\t*/\n\t_markInsert(parent, offset, howMany) {\n\t\tif (parent.root.is(\"rootElement\") && !parent.root._isLoaded) return;\n\t\tconst changeItem = {\n\t\t\ttype: \"insert\",\n\t\t\toffset,\n\t\t\thowMany,\n\t\t\tcount: this._changeCount++\n\t\t};\n\t\tthis._markChange(parent, changeItem);\n\t}\n\t/**\n\t* Saves and handles a remove change.\n\t*/\n\t_markRemove(parent, offset, howMany) {\n\t\tif (parent.root.is(\"rootElement\") && !parent.root._isLoaded) return;\n\t\tconst changeItem = {\n\t\t\ttype: \"remove\",\n\t\t\toffset,\n\t\t\thowMany,\n\t\t\tcount: this._changeCount++\n\t\t};\n\t\tthis._markChange(parent, changeItem);\n\t\tthis._removeAllNestedChanges(parent, offset, howMany);\n\t}\n\t/**\n\t* Saves and handles an attribute change.\n\t*/\n\t_markAttribute(item) {\n\t\tif (item.root.is(\"rootElement\") && !item.root._isLoaded) return;\n\t\tconst changeItem = {\n\t\t\ttype: \"attribute\",\n\t\t\toffset: item.startOffset,\n\t\t\thowMany: item.offsetSize,\n\t\t\tcount: this._changeCount++\n\t\t};\n\t\tthis._markChange(item.parent, changeItem);\n\t}\n\t/**\n\t* Saves and handles a model change.\n\t*/\n\t_markChange(parent, changeItem) {\n\t\tthis._makeSnapshots(parent);\n\t\tconst changes = this._getChangesForElement(parent);\n\t\tthis._handleChange(changeItem, changes);\n\t\tchanges.push(changeItem);\n\t\tfor (let i = 0; i < changes.length; i++) if (changes[i].howMany < 1) {\n\t\t\tchanges.splice(i, 1);\n\t\t\ti--;\n\t\t}\n\t}\n\t/**\n\t* Tries to set given state for given item.\n\t*\n\t* This method does simple validation (it sets the state only for model elements, not for text proxy nodes). It also follows state\n\t* setting rules, that is, `'refresh'` cannot overwrite `'rename'`, and `'rename'` cannot overwrite `'move'`.\n\t*/\n\t_setElementState(node, state) {\n\t\tif (!node.is(\"element\")) return;\n\t\tconst currentStatePriority = Differ._statesPriority.indexOf(this._elementState.get(node));\n\t\tif (Differ._statesPriority.indexOf(state) > currentStatePriority) this._elementState.set(node, state);\n\t}\n\t/**\n\t* Returns a value for {@link ~DifferItemAction `action`} property for diff items returned by {@link ~Differ#getChanges}.\n\t* This method aims to return `'rename'` or `'refresh'` when it should, and `diffItemType` (\"default action\") in all other cases.\n\t*\n\t* It bases on a few factors:\n\t*\n\t* * for text nodes, the method always returns `diffItemType`,\n\t* * for newly inserted element, the method returns `diffItemType`,\n\t* * if {@link ~Differ#_elementState element state} was not recorded, the method returns `diffItemType`,\n\t* * if state was recorded, and it was `'move'` (default action), the method returns `diffItemType`,\n\t* * finally, if state was `'refresh'` or `'rename'`, the method returns the state value.\n\t*/\n\t_getDiffActionForNode(node, diffItemType) {\n\t\tif (!node.is(\"element\")) return diffItemType;\n\t\tif (!this._elementsSnapshots.has(node)) return diffItemType;\n\t\tconst state = this._elementState.get(node);\n\t\tif (!state || state == \"move\") return diffItemType;\n\t\treturn state;\n\t}\n\t/**\n\t* Gets an array of changes that have already been saved for a given element.\n\t*/\n\t_getChangesForElement(element) {\n\t\tlet changes;\n\t\tif (this._changesInElement.has(element)) changes = this._changesInElement.get(element);\n\t\telse {\n\t\t\tchanges = [];\n\t\t\tthis._changesInElement.set(element, changes);\n\t\t}\n\t\treturn changes;\n\t}\n\t/**\n\t* Creates and saves a snapshot for all children of the given element.\n\t*/\n\t_makeSnapshots(element) {\n\t\tif (this._elementChildrenSnapshots.has(element)) return;\n\t\tconst childrenSnapshots = _getChildrenSnapshots(element.getChildren());\n\t\tthis._elementChildrenSnapshots.set(element, childrenSnapshots);\n\t\tfor (const snapshot of childrenSnapshots) this._elementsSnapshots.set(snapshot.node, snapshot);\n\t}\n\t/**\n\t* For a given newly saved change, compares it with a change already done on the element and modifies the incoming\n\t* change and/or the old change.\n\t*\n\t* @param inc Incoming (new) change.\n\t* @param changes An array containing all the changes done on that element.\n\t*/\n\t_handleChange(inc, changes) {\n\t\tinc.nodesToHandle = inc.howMany;\n\t\tfor (const old of changes) {\n\t\t\tconst incEnd = inc.offset + inc.howMany;\n\t\t\tconst oldEnd = old.offset + old.howMany;\n\t\t\tif (inc.type == \"insert\") {\n\t\t\t\tif (old.type == \"insert\") {\n\t\t\t\t\tif (inc.offset <= old.offset) old.offset += inc.howMany;\n\t\t\t\t\telse if (inc.offset < oldEnd) {\n\t\t\t\t\t\told.howMany += inc.nodesToHandle;\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (old.type == \"remove\") {\n\t\t\t\t\tif (inc.offset < old.offset) old.offset += inc.howMany;\n\t\t\t\t}\n\t\t\t\tif (old.type == \"attribute\") {\n\t\t\t\t\tif (inc.offset <= old.offset) old.offset += inc.howMany;\n\t\t\t\t\telse if (inc.offset < oldEnd) {\n\t\t\t\t\t\tconst howMany = old.howMany;\n\t\t\t\t\t\told.howMany = inc.offset - old.offset;\n\t\t\t\t\t\tchanges.unshift({\n\t\t\t\t\t\t\ttype: \"attribute\",\n\t\t\t\t\t\t\toffset: incEnd,\n\t\t\t\t\t\t\thowMany: howMany - old.howMany,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (inc.type == \"remove\") {\n\t\t\t\tif (old.type == \"insert\") {\n\t\t\t\t\tif (incEnd <= old.offset) old.offset -= inc.howMany;\n\t\t\t\t\telse if (incEnd <= oldEnd) if (inc.offset < old.offset) {\n\t\t\t\t\t\tconst intersectionLength = incEnd - old.offset;\n\t\t\t\t\t\told.offset = inc.offset;\n\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t\tinc.nodesToHandle -= intersectionLength;\n\t\t\t\t\t} else {\n\t\t\t\t\t\told.howMany -= inc.nodesToHandle;\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t}\n\t\t\t\t\telse if (inc.offset <= old.offset) {\n\t\t\t\t\t\tinc.nodesToHandle -= old.howMany;\n\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t} else if (inc.offset < oldEnd) {\n\t\t\t\t\t\tconst intersectionLength = oldEnd - inc.offset;\n\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t\tinc.nodesToHandle -= intersectionLength;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (old.type == \"remove\") {\n\t\t\t\t\tif (incEnd <= old.offset) old.offset -= inc.howMany;\n\t\t\t\t\telse if (inc.offset < old.offset) {\n\t\t\t\t\t\tinc.nodesToHandle += old.howMany;\n\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (old.type == \"attribute\") {\n\t\t\t\t\tif (incEnd <= old.offset) old.offset -= inc.howMany;\n\t\t\t\t\telse if (inc.offset < old.offset) {\n\t\t\t\t\t\tconst intersectionLength = incEnd - old.offset;\n\t\t\t\t\t\told.offset = inc.offset;\n\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t} else if (inc.offset < oldEnd) if (incEnd <= oldEnd) {\n\t\t\t\t\t\tconst howMany = old.howMany;\n\t\t\t\t\t\told.howMany = inc.offset - old.offset;\n\t\t\t\t\t\tconst howManyAfter = howMany - old.howMany - inc.nodesToHandle;\n\t\t\t\t\t\tchanges.unshift({\n\t\t\t\t\t\t\ttype: \"attribute\",\n\t\t\t\t\t\t\toffset: inc.offset,\n\t\t\t\t\t\t\thowMany: howManyAfter,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t});\n\t\t\t\t\t} else old.howMany -= oldEnd - inc.offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (inc.type == \"attribute\") {\n\t\t\t\tif (old.type == \"insert\") {\n\t\t\t\t\tif (inc.offset < old.offset && incEnd > old.offset) {\n\t\t\t\t\t\tif (incEnd > oldEnd) {\n\t\t\t\t\t\t\tconst attributePart = {\n\t\t\t\t\t\t\t\ttype: \"attribute\",\n\t\t\t\t\t\t\t\toffset: oldEnd,\n\t\t\t\t\t\t\t\thowMany: incEnd - oldEnd,\n\t\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tthis._handleChange(attributePart, changes);\n\t\t\t\t\t\t\tchanges.push(attributePart);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tinc.nodesToHandle = old.offset - inc.offset;\n\t\t\t\t\t\tinc.howMany = inc.nodesToHandle;\n\t\t\t\t\t} else if (inc.offset >= old.offset && inc.offset < oldEnd) if (incEnd > oldEnd) {\n\t\t\t\t\t\tinc.nodesToHandle = incEnd - oldEnd;\n\t\t\t\t\t\tinc.offset = oldEnd;\n\t\t\t\t\t} else inc.nodesToHandle = 0;\n\t\t\t\t}\n\t\t\t\tif (old.type == \"remove\") {\n\t\t\t\t\tif (inc.offset < old.offset && incEnd > old.offset) {\n\t\t\t\t\t\tconst attributePart = {\n\t\t\t\t\t\t\ttype: \"attribute\",\n\t\t\t\t\t\t\toffset: old.offset,\n\t\t\t\t\t\t\thowMany: incEnd - old.offset,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t};\n\t\t\t\t\t\tthis._handleChange(attributePart, changes);\n\t\t\t\t\t\tchanges.push(attributePart);\n\t\t\t\t\t\tinc.nodesToHandle = old.offset - inc.offset;\n\t\t\t\t\t\tinc.howMany = inc.nodesToHandle;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (old.type == \"attribute\") {\n\t\t\t\t\tif (inc.offset >= old.offset && incEnd <= oldEnd) {\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\tinc.howMany = 0;\n\t\t\t\t\t\tinc.offset = 0;\n\t\t\t\t\t} else if (inc.offset <= old.offset && incEnd >= oldEnd) old.howMany = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tinc.howMany = inc.nodesToHandle;\n\t\tdelete inc.nodesToHandle;\n\t}\n\t/**\n\t* Returns an object with a single insert change description.\n\t*\n\t* @param parent The element in which the change happened.\n\t* @param offset The offset at which change happened.\n\t* @param action Further specifies what kind of action led to generating this change.\n\t* @param elementSnapshot Snapshot of the inserted node after changes.\n\t* @param elementSnapshotBefore Snapshot of the inserted node before changes.\n\t* @returns The diff item.\n\t*/\n\t_getInsertDiff(parent, offset, action, elementSnapshot, elementSnapshotBefore) {\n\t\tconst diffItem = {\n\t\t\ttype: \"insert\",\n\t\t\tposition: ModelPosition._createAt(parent, offset),\n\t\t\tname: elementSnapshot.name,\n\t\t\tattributes: new Map(elementSnapshot.attributes),\n\t\t\tlength: 1,\n\t\t\tchangeCount: this._changeCount++,\n\t\t\taction\n\t\t};\n\t\tif (action != \"insert\" && elementSnapshotBefore) diffItem.before = {\n\t\t\tname: elementSnapshotBefore.name,\n\t\t\tattributes: new Map(elementSnapshotBefore.attributes)\n\t\t};\n\t\treturn diffItem;\n\t}\n\t/**\n\t* Returns an object with a single remove change description.\n\t*\n\t* @param parent The element in which change happened.\n\t* @param offset The offset at which change happened.\n\t* @param action Further specifies what kind of action led to generating this change.\n\t* @param elementSnapshot The snapshot of the removed node before changes.\n\t* @returns The diff item.\n\t*/\n\t_getRemoveDiff(parent, offset, action, elementSnapshot) {\n\t\treturn {\n\t\t\ttype: \"remove\",\n\t\t\taction,\n\t\t\tposition: ModelPosition._createAt(parent, offset),\n\t\t\tname: elementSnapshot.name,\n\t\t\tattributes: new Map(elementSnapshot.attributes),\n\t\t\tlength: 1,\n\t\t\tchangeCount: this._changeCount++\n\t\t};\n\t}\n\t/**\n\t* Returns an array of objects where each one is a single attribute change description.\n\t*\n\t* @param range The range where the change happened.\n\t* @param oldAttributes A map, map iterator or compatible object that contains attributes before the change.\n\t* @param newAttributes A map, map iterator or compatible object that contains attributes after the change.\n\t* @returns An array containing one or more diff items.\n\t*/\n\t_getAttributesDiff(range, oldAttributes, newAttributes) {\n\t\tconst diffs = [];\n\t\tnewAttributes = new Map(newAttributes);\n\t\tfor (const [key, oldValue] of oldAttributes) {\n\t\t\tconst newValue = newAttributes.has(key) ? newAttributes.get(key) : null;\n\t\t\tif (newValue !== oldValue) diffs.push({\n\t\t\t\ttype: \"attribute\",\n\t\t\t\tposition: range.start,\n\t\t\t\trange: range.clone(),\n\t\t\t\tlength: 1,\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\tattributeNewValue: newValue,\n\t\t\t\tchangeCount: this._changeCount++\n\t\t\t});\n\t\t\tnewAttributes.delete(key);\n\t\t}\n\t\tfor (const [key, newValue] of newAttributes) diffs.push({\n\t\t\ttype: \"attribute\",\n\t\t\tposition: range.start,\n\t\t\trange: range.clone(),\n\t\t\tlength: 1,\n\t\t\tattributeKey: key,\n\t\t\tattributeOldValue: null,\n\t\t\tattributeNewValue: newValue,\n\t\t\tchangeCount: this._changeCount++\n\t\t});\n\t\treturn diffs;\n\t}\n\t/**\n\t* Checks whether given element or any of its parents is an element that is buffered as an inserted element.\n\t*/\n\t_isInInsertedElement(element) {\n\t\tconst parent = element.parent;\n\t\tif (!parent) return false;\n\t\tconst changes = this._changesInElement.get(parent);\n\t\tconst offset = element.startOffset;\n\t\tif (changes) {\n\t\t\tfor (const change of changes) if (change.type == \"insert\" && offset >= change.offset && offset < change.offset + change.howMany) return true;\n\t\t}\n\t\treturn this._isInInsertedElement(parent);\n\t}\n\t/**\n\t* Removes deeply all buffered changes that are registered in elements from range specified by `parent`, `offset`\n\t* and `howMany`.\n\t*/\n\t_removeAllNestedChanges(parent, offset, howMany) {\n\t\tconst range = new ModelRange(ModelPosition._createAt(parent, offset), ModelPosition._createAt(parent, offset + howMany));\n\t\tfor (const item of range.getItems({ shallow: true })) if (item.is(\"element\")) {\n\t\t\tthis._changesInElement.delete(item);\n\t\t\tthis._removeAllNestedChanges(item, 0, item.maxOffset);\n\t\t}\n\t}\n};\n/**\n* Returns a snapshot for the specified child node. Text node snapshots have the `name` property set to `$text`.\n*/\nfunction _getSingleNodeSnapshot(node) {\n\treturn {\n\t\tnode,\n\t\tname: node.is(\"$text\") ? \"$text\" : node.name,\n\t\tattributes: new Map(node.getAttributes())\n\t};\n}\n/**\n* Returns an array that is a copy of passed child list with the exception that text nodes are split to one or more\n* objects, each representing one character and attributes set on that character.\n*/\nfunction _getChildrenSnapshots(children) {\n\tconst snapshots = [];\n\tfor (const child of children) if (child.is(\"$text\")) for (let i = 0; i < child.data.length; ++i) snapshots.push(_getSingleNodeSnapshot(child));\n\telse snapshots.push(_getSingleNodeSnapshot(child));\n\treturn snapshots;\n}\n/**\n* Generates array of diff instructions for given changes set.\n*\n* Generated actions are:\n*\n* - 'e' for 'equal' - when item at that position did not change,\n* - 'i' for 'insert' - when item at that position was inserted,\n* - 'r' for 'remove' - when item at that position was removed,\n* - 'a' for 'attribute' - when item at that position has it attributes changed.\n*\n* Example (assume that uppercase letters have bold attribute, compare with function code):\n*\n* children before:\tfooBAR\n* children after:\tfoxybAR\n*\n* changes: type: remove, offset: 1, howMany: 1\n*\t\t\ttype: insert, offset: 2, howMany: 2\n*\t\t\ttype: attribute, offset: 4, howMany: 1\n*\n* Expected actions: equal (f), remove (o), equal (o), insert (x), insert (y), attribute (b), equal (A), equal (R)\n*\n* Steps taken by the script:\n*\n* 1. change = \"type: remove, offset: 1, howMany: 1\"; offset = 0; oldChildrenHandled = 0\n* 1.1 between this change and the beginning is one not-changed node, fill with one equal action, one old child has been handled\n* 1.2 this change removes one node, add one remove action\n* 1.3 change last visited `offset` to 1\n* 1.4 since an old child has been removed, one more old child has been handled\n* 1.5 actions at this point are: equal, remove\n*\n* 2. change = \"type: insert, offset: 2, howMany: 2\"; offset = 1; oldChildrenHandled = 2\n* 2.1 between this change and previous change is one not-changed node, add equal action, another one old children has been handled\n* 2.2 this change inserts two nodes, add two insert actions\n* 2.3 change last visited offset to the end of the inserted range, that is 4\n* 2.4 actions at this point are: equal, remove, equal, insert, insert\n*\n* 3. change = \"type: attribute, offset: 4, howMany: 1\"; offset = 4, oldChildrenHandled = 3\n* 3.1 between this change and previous change are no not-changed nodes\n* 3.2 this change changes one node, add one attribute action\n* 3.3 change last visited `offset` to the end of change range, that is 5\n* 3.4 since an old child has been changed, one more old child has been handled\n* 3.5 actions at this point are: equal, remove, equal, insert, insert, attribute\n*\n* 4. after loop oldChildrenHandled = 4, oldChildrenLength = 6 (fooBAR is 6 characters)\n* 4.1 fill up with two equal actions\n*\n* The result actions are: equal, remove, equal, insert, insert, attribute, equal, equal.\n*/\nfunction _generateDiffInstructionsFromChanges(oldChildrenLength, changes) {\n\tconst diff = [];\n\tlet offset = 0;\n\tlet oldChildrenHandled = 0;\n\tfor (const change of changes) {\n\t\tif (change.offset > offset) {\n\t\t\tfor (let i = 0; i < change.offset - offset; i++) diff.push(\"e\");\n\t\t\toldChildrenHandled += change.offset - offset;\n\t\t}\n\t\tif (change.type == \"insert\") {\n\t\t\tfor (let i = 0; i < change.howMany; i++) diff.push(\"i\");\n\t\t\toffset = change.offset + change.howMany;\n\t\t} else if (change.type == \"remove\") {\n\t\t\tfor (let i = 0; i < change.howMany; i++) diff.push(\"r\");\n\t\t\toffset = change.offset;\n\t\t\toldChildrenHandled += change.howMany;\n\t\t} else {\n\t\t\tif (change.howMany > 1500) for (let i = 0; i < change.howMany; i++) diff.push(\"a\");\n\t\t\telse diff.push(...\"a\".repeat(change.howMany).split(\"\"));\n\t\t\toffset = change.offset + change.howMany;\n\t\t\toldChildrenHandled += change.howMany;\n\t\t}\n\t}\n\tif (oldChildrenHandled < oldChildrenLength) for (let i = 0; i < oldChildrenLength - oldChildrenHandled - offset; i++) diff.push(\"e\");\n\treturn diff;\n}\n/**\n* Filter callback for `Array.filter` that filters out change entries that are in graveyard.\n*/\nfunction _changesInGraveyardFilter(entry) {\n\tconst posInGy = \"position\" in entry && entry.position.root.rootName == \"$graveyard\";\n\tconst rangeInGy = \"range\" in entry && entry.range.root.rootName == \"$graveyard\";\n\treturn !posInGy && !rangeInGy;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* `History` keeps the track of all the operations applied to the {@link module:engine/model/document~ModelDocument document}.\n*/\nvar History = class {\n\t/**\n\t* Operations added to the history.\n\t*/\n\t_operations = [];\n\t/**\n\t* Holds an information which {@link module:engine/model/operation/operation~Operation operation} undoes which\n\t* {@link module:engine/model/operation/operation~Operation operation}.\n\t*\n\t* Keys of the map are \"undoing operations\", that is operations that undone some other operations. For each key, the\n\t* value is an operation that has been undone by the \"undoing operation\".\n\t*/\n\t_undoPairs = /* @__PURE__ */ new Map();\n\t/**\n\t* Holds all undone operations.\n\t*/\n\t_undoneOperations = /* @__PURE__ */ new Set();\n\t/**\n\t* A map that allows retrieving the operations fast based on the given base version.\n\t*/\n\t_baseVersionToOperationIndex = /* @__PURE__ */ new Map();\n\t/**\n\t* The history version.\n\t*/\n\t_version = 0;\n\t/**\n\t* The gap pairs kept in the <from,to> format.\n\t*\n\t* Anytime the `history.version` is set to a version larger than `history.version + 1`,\n\t* a new <lastHistoryVersion, newHistoryVersion> entry is added to the map.\n\t*/\n\t_gaps = /* @__PURE__ */ new Map();\n\t/**\n\t* The version of the last operation in the history.\n\t*\n\t* The history version is incremented automatically when a new operation is added to the history.\n\t* Setting the version manually should be done only in rare circumstances when a gap is planned\n\t* between history versions. When doing so, a gap will be created and the history will accept adding\n\t* an operation with base version equal to the new history version.\n\t*/\n\tget version() {\n\t\treturn this._version;\n\t}\n\tset version(version) {\n\t\tif (this._operations.length && version > this._version + 1) this._gaps.set(this._version, version);\n\t\tthis._version = version;\n\t}\n\t/**\n\t* The last history operation.\n\t*/\n\tget lastOperation() {\n\t\treturn this._operations[this._operations.length - 1];\n\t}\n\t/**\n\t* Adds an operation to the history and increments the history version.\n\t*\n\t* The operation's base version should be equal to the history version. Otherwise an error is thrown.\n\t*/\n\taddOperation(operation) {\n\t\tif (operation.baseVersion !== this.version)\n /**\n\t\t* Only operations with matching versions can be added to the history.\n\t\t*\n\t\t* @error model-document-history-addoperation-incorrect-version\n\t\t* @param {module:engine/model/operation/operation~Operation} operation The current operation.\n\t\t* @param {number} historyVersion The current document history version.\n\t\t*/\n\t\tthrow new CKEditorError(\"model-document-history-addoperation-incorrect-version\", this, {\n\t\t\toperation,\n\t\t\thistoryVersion: this.version\n\t\t});\n\t\tthis._operations.push(operation);\n\t\tthis._version++;\n\t\tthis._baseVersionToOperationIndex.set(operation.baseVersion, this._operations.length - 1);\n\t}\n\t/**\n\t* Returns operations from the given range of operation base versions that were added to the history.\n\t*\n\t* Note that there may be gaps in operations base versions.\n\t*\n\t* @param fromBaseVersion Base version from which operations should be returned (inclusive).\n\t* @param toBaseVersion Base version up to which operations should be returned (exclusive).\n\t* @returns History operations for the given range, in chronological order.\n\t*/\n\tgetOperations(fromBaseVersion, toBaseVersion = this.version) {\n\t\tif (!this._operations.length) return [];\n\t\tconst firstOperation = this._operations[0];\n\t\tif (fromBaseVersion === void 0) fromBaseVersion = firstOperation.baseVersion;\n\t\tlet inclusiveTo = toBaseVersion - 1;\n\t\tfor (const [gapFrom, gapTo] of this._gaps) {\n\t\t\tif (fromBaseVersion > gapFrom && fromBaseVersion < gapTo) fromBaseVersion = gapTo;\n\t\t\tif (inclusiveTo > gapFrom && inclusiveTo < gapTo) inclusiveTo = gapFrom - 1;\n\t\t}\n\t\tif (inclusiveTo < firstOperation.baseVersion || fromBaseVersion > this.lastOperation.baseVersion) return [];\n\t\tlet fromIndex = this._baseVersionToOperationIndex.get(fromBaseVersion);\n\t\tif (fromIndex === void 0) fromIndex = 0;\n\t\tlet toIndex = this._baseVersionToOperationIndex.get(inclusiveTo);\n\t\tif (toIndex === void 0) toIndex = this._operations.length - 1;\n\t\treturn this._operations.slice(fromIndex, toIndex + 1);\n\t}\n\t/**\n\t* Returns operation from the history that bases on given `baseVersion`.\n\t*\n\t* @param baseVersion Base version of the operation to get.\n\t* @returns Operation with given base version or `undefined` if there is no such operation in history.\n\t*/\n\tgetOperation(baseVersion) {\n\t\tconst operationIndex = this._baseVersionToOperationIndex.get(baseVersion);\n\t\tif (operationIndex === void 0) return;\n\t\treturn this._operations[operationIndex];\n\t}\n\t/**\n\t* Marks in history that one operation is an operation that is undoing the other operation. By marking operation this way,\n\t* history is keeping more context information about operations, which helps in operational transformation.\n\t*\n\t* @param undoneOperation Operation which is undone by `undoingOperation`.\n\t* @param undoingOperation Operation which undoes `undoneOperation`.\n\t*/\n\tsetOperationAsUndone(undoneOperation, undoingOperation) {\n\t\tthis._undoPairs.set(undoingOperation, undoneOperation);\n\t\tthis._undoneOperations.add(undoneOperation);\n\t}\n\t/**\n\t* Checks whether given `operation` is undoing any other operation.\n\t*\n\t* @param operation Operation to check.\n\t* @returns `true` if given `operation` is undoing any other operation, `false` otherwise.\n\t*/\n\tisUndoingOperation(operation) {\n\t\treturn this._undoPairs.has(operation);\n\t}\n\t/**\n\t* Checks whether given `operation` has been undone by any other operation.\n\t*\n\t* @param operation Operation to check.\n\t* @returns `true` if given `operation` has been undone any other operation, `false` otherwise.\n\t*/\n\tisUndoneOperation(operation) {\n\t\treturn this._undoneOperations.has(operation);\n\t}\n\t/**\n\t* For given `undoingOperation`, returns the operation which has been undone by it.\n\t*\n\t* @returns Operation that has been undone by given `undoingOperation` or `undefined`\n\t* if given `undoingOperation` is not undoing any other operation.\n\t*/\n\tgetUndoneOperation(undoingOperation) {\n\t\treturn this._undoPairs.get(undoingOperation);\n\t}\n\t/**\n\t* Resets the history of operations.\n\t*/\n\treset() {\n\t\tthis._version = 0;\n\t\tthis._undoPairs = /* @__PURE__ */ new Map();\n\t\tthis._operations = [];\n\t\tthis._undoneOperations = /* @__PURE__ */ new Set();\n\t\tthis._gaps = /* @__PURE__ */ new Map();\n\t\tthis._baseVersionToOperationIndex = /* @__PURE__ */ new Map();\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/rootelement\n*/\n/**\n* Type of {@link module:engine/model/element~ModelElement} that is a root of a model tree.\n*/\nvar ModelRootElement = class extends ModelElement {\n\t/**\n\t* Unique root name used to identify this root element by {@link module:engine/model/document~ModelDocument}.\n\t*/\n\trootName;\n\t/**\n\t* Document that is an owner of this root.\n\t*/\n\t_document;\n\t/**\n\t* @internal\n\t*/\n\t_isAttached = true;\n\t/**\n\t* Informs if the root element is loaded (default).\n\t*\n\t* @internal\n\t*/\n\t_isLoaded = true;\n\t/**\n\t* Creates root element.\n\t*\n\t* @param document Document that is an owner of this root.\n\t* @param name Node name.\n\t* @param rootName Unique root name used to identify this root element by {@link module:engine/model/document~ModelDocument}.\n\t*/\n\tconstructor(document, name, rootName = \"main\") {\n\t\tsuper(name);\n\t\tthis._document = document;\n\t\tthis.rootName = rootName;\n\t}\n\t/**\n\t* {@link module:engine/model/document~ModelDocument Document} that owns this root element.\n\t*/\n\tget document() {\n\t\treturn this._document;\n\t}\n\t/**\n\t* Informs if the root element is currently attached to the document, or not.\n\t*\n\t* A detached root is equivalent to being removed and cannot contain any children or markers.\n\t*\n\t* By default, a newly added root is attached. It can be detached using\n\t* {@link module:engine/model/writer~ModelWriter#detachRoot `Writer#detachRoot`}. A detached root can be re-attached again using\n\t* {@link module:engine/model/writer~ModelWriter#addRoot `Writer#addRoot`}.\n\t*/\n\tisAttached() {\n\t\treturn this._isAttached;\n\t}\n\t/**\n\t* Converts `RootElement` instance to `string` containing its name.\n\t*\n\t* @returns `RootElement` instance converted to `string`.\n\t*/\n\ttoJSON() {\n\t\treturn this.rootName;\n\t}\n};\nModelRootElement.prototype.is = function(type, name) {\n\tif (!name) return type === \"rootElement\" || type === \"model:rootElement\" || type === \"element\" || type === \"model:element\" || type === \"node\" || type === \"model:node\";\n\treturn name === this.name && (type === \"rootElement\" || type === \"model:rootElement\" || type === \"element\" || type === \"model:element\");\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/document\n*/\nconst graveyardName = \"$graveyard\";\nconst ModelDocumentBase = /* #__PURE__ */ EmitterMixin();\n/**\n* Data model's document. It contains the model's structure, its selection and the history of changes.\n*\n* Read more about working with the model in\n* {@glink framework/architecture/editing-engine#model introduction to the the editing engine's architecture}.\n*\n* Usually, the document contains just one {@link module:engine/model/document~ModelDocument#roots root element}, so\n* you can retrieve it by just calling {@link module:engine/model/document~ModelDocument#getRoot} without specifying its name:\n*\n* ```ts\n* model.document.getRoot(); // -> returns the main root\n* ```\n*\n* However, the document may contain multiple roots – e.g. when the editor has multiple editable areas\n* (e.g. a title and a body of a message).\n*/\nvar ModelDocument = class extends ModelDocumentBase {\n\t/**\n\t* The {@link module:engine/model/model~Model model} that the document is a part of.\n\t*/\n\tmodel;\n\t/**\n\t* The document's history.\n\t*/\n\thistory;\n\t/**\n\t* The selection in this document.\n\t*/\n\tselection;\n\t/**\n\t* A list of roots that are owned and managed by this document. Use {@link #createRoot}, {@link #getRoot} and\n\t* {@link #getRootNames} to manipulate it.\n\t*/\n\troots;\n\t/**\n\t* The model differ object. Its role is to buffer changes done on the model document and then calculate a diff of those changes.\n\t*/\n\tdiffer;\n\t/**\n\t* Defines whether the document is in a read-only mode.\n\t*\n\t* The user should not be able to change the data of a document that is read-only.\n\t*\n\t* @readonly\n\t*/\n\tisReadOnly;\n\t/**\n\t* Post-fixer callbacks registered to the model document.\n\t*/\n\t_postFixers;\n\t/**\n\t* A flag that indicates whether the selection has changed since last change block.\n\t*/\n\t_hasSelectionChangedFromTheLastChangeBlock;\n\t/**\n\t* Creates an empty document instance with no {@link #roots} (other than\n\t* the {@link #graveyard graveyard root}).\n\t*/\n\tconstructor(model) {\n\t\tsuper();\n\t\tthis.model = model;\n\t\tthis.history = new History();\n\t\tthis.selection = new ModelDocumentSelection(this);\n\t\tthis.roots = new Collection({ idProperty: \"rootName\" });\n\t\tthis.differ = new Differ(model.markers);\n\t\tthis.isReadOnly = false;\n\t\tthis._postFixers = /* @__PURE__ */ new Set();\n\t\tthis._hasSelectionChangedFromTheLastChangeBlock = false;\n\t\tthis.createRoot(\"$root\", graveyardName);\n\t\tthis.listenTo(model, \"applyOperation\", (evt, args) => {\n\t\t\tconst operation = args[0];\n\t\t\tif (operation.isDocumentOperation) this.differ.bufferOperation(operation);\n\t\t}, { priority: \"high\" });\n\t\tthis.listenTo(model, \"applyOperation\", (evt, args) => {\n\t\t\tconst operation = args[0];\n\t\t\tif (operation.isDocumentOperation) this.history.addOperation(operation);\n\t\t}, { priority: \"low\" });\n\t\tthis.listenTo(this.selection, \"change\", () => {\n\t\t\tthis._hasSelectionChangedFromTheLastChangeBlock = true;\n\t\t});\n\t\tthis.listenTo(model.markers, \"update\", (evt, marker, oldRange, newRange, oldMarkerData) => {\n\t\t\tconst newMarkerData = {\n\t\t\t\t...marker.getData(),\n\t\t\t\trange: newRange\n\t\t\t};\n\t\t\tthis.differ.bufferMarkerChange(marker.name, oldMarkerData, newMarkerData);\n\t\t\tif (oldRange === null) marker.on(\"change\", (evt, oldRange) => {\n\t\t\t\tconst markerData = marker.getData();\n\t\t\t\tthis.differ.bufferMarkerChange(marker.name, {\n\t\t\t\t\t...markerData,\n\t\t\t\t\trange: oldRange\n\t\t\t\t}, markerData);\n\t\t\t});\n\t\t});\n\t\tthis.registerPostFixer((writer) => {\n\t\t\tlet result = false;\n\t\t\tfor (const root of this.roots) if (!root.isAttached() && !root.isEmpty) {\n\t\t\t\twriter.remove(writer.createRangeIn(root));\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t\tfor (const marker of this.model.markers) if (!marker.getRange().root.isAttached()) {\n\t\t\t\twriter.removeMarker(marker);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t\treturn result;\n\t\t});\n\t}\n\t/**\n\t* The document version. Every applied operation increases the version number. It is used to\n\t* ensure that operations are applied on a proper document version.\n\t*\n\t* This property is equal to {@link module:engine/model/history~History#version `model.Document#history#version`}.\n\t*\n\t* If the {@link module:engine/model/operation/operation~Operation#baseVersion base version} does not match the document version,\n\t* a {@link module:utils/ckeditorerror~CKEditorError model-document-applyoperation-wrong-version} error is thrown.\n\t*/\n\tget version() {\n\t\treturn this.history.version;\n\t}\n\tset version(version) {\n\t\tthis.history.version = version;\n\t}\n\t/**\n\t* The graveyard tree root. A document always has a graveyard root that stores removed nodes.\n\t*/\n\tget graveyard() {\n\t\treturn this.getRoot(graveyardName);\n\t}\n\t/**\n\t* Creates a new root.\n\t*\n\t* **Note:** do not use this method after the editor has been initialized! If you want to dynamically add a root, use\n\t* {@link module:engine/model/writer~ModelWriter#addRoot `model.Writer#addRoot`} instead.\n\t*\n\t* **Note:** The default `elementName` value is `'$root'`. When the editor uses a custom root\n\t* {@link module:core/editor/editorconfig~RootConfig#modelElement `modelElement`}, pass the configured model element\n\t* name explicitly so the created root matches the schema the features expect.\n\t* See the {@glink framework/deep-dive/schema#custom-root-elements Custom root elements} section of the\n\t* {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*\n\t* @param elementName The element name. Defaults to `'$root'` which also has some basic schema defined\n\t* (e.g. `$block` elements are allowed inside the `$root`). Make sure to define a proper schema if you use a different name.\n\t* @param rootName A unique root name.\n\t* @returns The created root.\n\t*/\n\tcreateRoot(elementName = \"$root\", rootName = \"main\") {\n\t\tif (this.roots.get(rootName))\n /**\n\t\t* A root with the specified name already exists.\n\t\t*\n\t\t* @error model-document-createroot-name-exists\n\t\t*/\n\t\tthrow new CKEditorError(\"model-document-createroot-name-exists\", this, { name: rootName });\n\t\tconst root = new ModelRootElement(this, elementName, rootName);\n\t\tthis.roots.add(root);\n\t\treturn root;\n\t}\n\t/**\n\t* Removes all event listeners set by the document instance.\n\t*/\n\tdestroy() {\n\t\tthis.selection.destroy();\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Returns a root by its name.\n\t*\n\t* Detached roots are returned by this method. This is to be able to operate on the detached root (for example, to be able to create\n\t* a position inside such a root for undo feature purposes).\n\t*\n\t* @param name The root name of the root to return.\n\t* @returns The root registered under a given name or `null` when there is no root with the given name.\n\t*/\n\tgetRoot(name = \"main\") {\n\t\treturn this.roots.get(name);\n\t}\n\t/**\n\t* Returns an array with names of all roots added to the document (except the {@link #graveyard graveyard root}).\n\t*\n\t* Detached roots **are not** returned by this method by default. This is to make sure that all features or algorithms that operate\n\t* on the document data know which roots are still a part of the document and should be processed.\n\t*\n\t* @param includeDetached Specified whether detached roots should be returned as well.\n\t*/\n\tgetRootNames(includeDetached = false) {\n\t\treturn this.getRoots(includeDetached).map((root) => root.rootName);\n\t}\n\t/**\n\t* Returns an array with all roots added to the document (except the {@link #graveyard graveyard root}).\n\t*\n\t* Detached roots **are not** returned by this method by default. This is to make sure that all features or algorithms that operate\n\t* on the document data know which roots are still a part of the document and should be processed.\n\t*\n\t* @param includeDetached Specified whether detached roots should be returned as well.\n\t*/\n\tgetRoots(includeDetached = false) {\n\t\treturn this.roots.filter((root) => root != this.graveyard && (includeDetached || root.isAttached()) && root._isLoaded);\n\t}\n\t/**\n\t* Used to register a post-fixer callback. A post-fixer mechanism guarantees that the features\n\t* will operate on a correct model state.\n\t*\n\t* An execution of a feature may lead to an incorrect document tree state. The callbacks are used to fix the document tree after\n\t* it has changed. Post-fixers are fired just after all changes from the outermost change block were applied but\n\t* before the {@link module:engine/model/document~ModelDocument#event:change change event} is fired. If a post-fixer callback made\n\t* a change, it should return `true`. When this happens, all post-fixers are fired again to check if something else should\n\t* not be fixed in the new document tree state.\n\t*\n\t* As a parameter, a post-fixer callback receives a {@link module:engine/model/writer~ModelWriter writer} instance connected with the\n\t* executed changes block. Thanks to that, all changes done by the callback will be added to the same\n\t* {@link module:engine/model/batch~Batch batch} (and undo step) as the original changes. This makes post-fixer changes transparent\n\t* for the user.\n\t*\n\t* An example of a post-fixer is a callback that checks if all the data were removed from the editor. If so, the\n\t* callback should add an empty paragraph so that the editor is never empty:\n\t*\n\t* ```ts\n\t* document.registerPostFixer( writer => {\n\t* \tconst changes = document.differ.getChanges();\n\t*\n\t* \t// Check if the changes lead to an empty root in the editor.\n\t* \tfor ( const entry of changes ) {\n\t* \t\tif ( entry.type == 'remove' && entry.position.root.isEmpty ) {\n\t* \t\t\twriter.insertElement( 'paragraph', entry.position.root, 0 );\n\t*\n\t* \t\t\t// It is fine to return early, even if multiple roots would need to be fixed.\n\t* \t\t\t// All post-fixers will be fired again, so if there are more empty roots, those will be fixed, too.\n\t* \t\t\treturn true;\n\t* \t\t}\n\t* \t}\n\t*\n\t* \treturn false;\n\t* } );\n\t* ```\n\t*/\n\tregisterPostFixer(postFixer) {\n\t\tthis._postFixers.add(postFixer);\n\t}\n\t/**\n\t* A custom `toJSON()` method to solve child-parent circular dependencies.\n\t*\n\t* @returns A clone of this object with the document property changed to a string.\n\t*/\n\ttoJSON() {\n\t\tconst json = clone(this);\n\t\tjson.selection = \"[engine.model.DocumentSelection]\";\n\t\tjson.model = \"[engine.model.Model]\";\n\t\treturn json;\n\t}\n\t/**\n\t* Check if there were any changes done on document, and if so, call post-fixers,\n\t* fire `change` event for features and conversion and then reset the differ.\n\t* Fire `change:data` event when at least one operation or buffered marker changes the data.\n\t*\n\t* @internal\n\t* @fires change\n\t* @fires change:data\n\t* @param writer The writer on which post-fixers will be called.\n\t*/\n\t_handleChangeBlock(writer) {\n\t\tif (this._hasDocumentChangedFromTheLastChangeBlock()) {\n\t\t\tthis._callPostFixers(writer);\n\t\t\tthis.selection.refresh();\n\t\t\tif (this.differ.hasDataChanges()) this.fire(\"change:data\", writer.batch);\n\t\t\telse this.fire(\"change\", writer.batch);\n\t\t\tthis.selection.refresh();\n\t\t\tthis.differ.reset();\n\t\t}\n\t\tthis._hasSelectionChangedFromTheLastChangeBlock = false;\n\t}\n\t/**\n\t* Returns whether there is a buffered change or if the selection has changed from the last\n\t* {@link module:engine/model/model~Model#enqueueChange `enqueueChange()` block}\n\t* or {@link module:engine/model/model~Model#change `change()` block}.\n\t*\n\t* @returns Returns `true` if document has changed from the last `change()` or `enqueueChange()` block.\n\t*/\n\t_hasDocumentChangedFromTheLastChangeBlock() {\n\t\treturn !this.differ.isEmpty || this._hasSelectionChangedFromTheLastChangeBlock;\n\t}\n\t/**\n\t* Returns the default root for this document which is either the first root that was added to the document using\n\t* {@link #createRoot} or the {@link #graveyard graveyard root} if no other roots were created.\n\t*\n\t* @returns The default root for this document.\n\t*/\n\t_getDefaultRoot() {\n\t\tconst roots = this.getRoots();\n\t\treturn roots.length ? roots[0] : this.graveyard;\n\t}\n\t/**\n\t* Returns the default range for this selection. The default range is a collapsed range that starts and ends\n\t* at the beginning of this selection's document {@link #_getDefaultRoot default root}.\n\t*\n\t* @internal\n\t*/\n\t_getDefaultRange() {\n\t\tconst defaultRoot = this._getDefaultRoot();\n\t\tconst model = this.model;\n\t\tconst schema = model.schema;\n\t\tconst position = model.createPositionFromPath(defaultRoot, [0]);\n\t\treturn schema.getNearestSelectionRange(position) || model.createRange(position);\n\t}\n\t/**\n\t* Checks whether a given {@link module:engine/model/range~ModelRange range} is a valid range for\n\t* the {@link #selection document's selection}.\n\t*\n\t* @internal\n\t* @param range A range to check.\n\t* @returns `true` if `range` is valid, `false` otherwise.\n\t*/\n\t_validateSelectionRange(range) {\n\t\treturn range.start.isValid() && range.end.isValid() && validateTextNodePosition(range.start) && validateTextNodePosition(range.end);\n\t}\n\t/**\n\t* Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.\n\t*\n\t* @param writer The writer on which post-fixer callbacks will be called.\n\t*/\n\t_callPostFixers(writer) {\n\t\tlet wasFixed = false;\n\t\tdo\n\t\t\tfor (const callback of this._postFixers) {\n\t\t\t\tthis.selection.refresh();\n\t\t\t\twasFixed = callback(writer);\n\t\t\t\tif (wasFixed) break;\n\t\t\t}\n\t\twhile (wasFixed);\n\t}\n};\n/**\n* Checks whether given range boundary position is valid for document selection, meaning that is not between\n* unicode surrogate pairs or base character and combining marks.\n*/\nfunction validateTextNodePosition(rangeBoundary) {\n\tconst textNode = rangeBoundary.textNode;\n\tif (textNode) {\n\t\tconst data = textNode.data;\n\t\tconst offset = rangeBoundary.offset - textNode.startOffset;\n\t\treturn !isInsideSurrogatePair(data, offset) && !isInsideCombinedSymbol(data, offset);\n\t}\n\treturn true;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/markercollection\n*/\nconst MarkerCollectionBase = /* #__PURE__ */ EmitterMixin();\nconst MarkerBase = /* #__PURE__ */ EmitterMixin(ModelTypeCheckable);\n/**\n* The collection of all {@link module:engine/model/markercollection~Marker markers} attached to the document.\n* It lets you {@link module:engine/model/markercollection~MarkerCollection#get get} markers or track them using\n* {@link module:engine/model/markercollection~MarkerCollection#event:update} event.\n*\n* To create, change or remove makers use {@link module:engine/model/writer~ModelWriter model writers'} methods:\n* {@link module:engine/model/writer~ModelWriter#addMarker} or {@link module:engine/model/writer~ModelWriter#removeMarker}. Since\n* the writer is the only proper way to change the data model it is not possible to change markers directly using this\n* collection. All markers created by the writer will be automatically added to this collection.\n*\n* By default there is one marker collection available as {@link module:engine/model/model~Model#markers model property}.\n*\n* @see module:engine/model/markercollection~Marker\n*/\nvar MarkerCollection = class extends MarkerCollectionBase {\n\t/**\n\t* Stores {@link ~Marker markers} added to the collection.\n\t*/\n\t_markers = /* @__PURE__ */ new Map();\n\t/**\n\t* Iterable interface.\n\t*\n\t* Iterates over all {@link ~Marker markers} added to the collection.\n\t*/\n\t[Symbol.iterator]() {\n\t\treturn this._markers.values();\n\t}\n\t/**\n\t* Checks if given {@link ~Marker marker} or marker name is in the collection.\n\t*\n\t* @param markerOrName Name of marker or marker instance to check.\n\t* @returns `true` if marker is in the collection, `false` otherwise.\n\t*/\n\thas(markerOrName) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\treturn this._markers.has(markerName);\n\t}\n\t/**\n\t* Returns {@link ~Marker marker} with given `markerName`.\n\t*\n\t* @param markerName Name of marker to get.\n\t* @returns Marker with given name or `null` if such marker was\n\t* not added to the collection.\n\t*/\n\tget(markerName) {\n\t\treturn this._markers.get(markerName) || null;\n\t}\n\t/**\n\t* Creates and adds a {@link ~Marker marker} to the `MarkerCollection` with given name on given\n\t* {@link module:engine/model/range~ModelRange range}.\n\t*\n\t* If `MarkerCollection` already had a marker with given name (or {@link ~Marker marker} was passed), the marker in\n\t* collection is updated and {@link module:engine/model/markercollection~MarkerCollection#event:update} event is fired\n\t* but only if there was a change (marker range or {@link module:engine/model/markercollection~Marker#managedUsingOperations}\n\t* flag has changed.\n\t*\n\t* @internal\n\t* @fires update\n\t* @param markerOrName Name of marker to set or marker instance to update.\n\t* @param range Marker range.\n\t* @param managedUsingOperations Specifies whether the marker is managed using operations.\n\t* @param affectsData Specifies whether the marker affects the data produced by the data pipeline\n\t* (is persisted in the editor's data).\n\t* @returns `Marker` instance which was added or updated.\n\t*/\n\t_set(markerOrName, range, managedUsingOperations = false, affectsData = false) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tif (markerName.includes(\",\"))\n /**\n\t\t* Marker name cannot contain the \",\" character.\n\t\t*\n\t\t* @error markercollection-incorrect-marker-name\n\t\t*/\n\t\tthrow new CKEditorError(\"markercollection-incorrect-marker-name\", this);\n\t\tconst oldMarker = this._markers.get(markerName);\n\t\tif (oldMarker) {\n\t\t\tconst oldMarkerData = oldMarker.getData();\n\t\t\tconst oldRange = oldMarker.getRange();\n\t\t\tlet hasChanged = false;\n\t\t\tif (!oldRange.isEqual(range)) {\n\t\t\t\toldMarker._attachLiveRange(ModelLiveRange.fromRange(range));\n\t\t\t\thasChanged = true;\n\t\t\t}\n\t\t\tif (managedUsingOperations != oldMarker.managedUsingOperations) {\n\t\t\t\toldMarker._managedUsingOperations = managedUsingOperations;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\t\t\tif (typeof affectsData === \"boolean\" && affectsData != oldMarker.affectsData) {\n\t\t\t\toldMarker._affectsData = affectsData;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\t\t\tif (hasChanged) this.fire(`update:${markerName}`, oldMarker, oldRange, range, oldMarkerData);\n\t\t\treturn oldMarker;\n\t\t}\n\t\tconst liveRange = ModelLiveRange.fromRange(range);\n\t\tconst marker = new Marker(markerName, liveRange, managedUsingOperations, affectsData);\n\t\tthis._markers.set(markerName, marker);\n\t\tthis.fire(`update:${markerName}`, marker, null, range, {\n\t\t\t...marker.getData(),\n\t\t\trange: null\n\t\t});\n\t\treturn marker;\n\t}\n\t/**\n\t* Removes given {@link ~Marker marker} or a marker with given name from the `MarkerCollection`.\n\t*\n\t* @internal\n\t* @fires update\n\t* @param markerOrName Marker or name of a marker to remove.\n\t* @returns `true` if marker was found and removed, `false` otherwise.\n\t*/\n\t_remove(markerOrName) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst oldMarker = this._markers.get(markerName);\n\t\tif (oldMarker) {\n\t\t\tthis._markers.delete(markerName);\n\t\t\tthis.fire(`update:${markerName}`, oldMarker, oldMarker.getRange(), null, oldMarker.getData());\n\t\t\tthis._destroyMarker(oldMarker);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\t/**\n\t* Fires an {@link module:engine/model/markercollection~MarkerCollection#event:update} event for the given {@link ~Marker marker}\n\t* but does not change the marker. Useful to force {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher downcast\n\t* conversion} for the marker.\n\t*\n\t* @internal\n\t* @fires update\n\t* @param markerOrName Marker or name of a marker to refresh.\n\t*/\n\t_refresh(markerOrName) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst marker = this._markers.get(markerName);\n\t\tif (!marker)\n /**\n\t\t* Marker with provided name does not exists.\n\t\t*\n\t\t* @error markercollection-refresh-marker-not-exists\n\t\t*/\n\t\tthrow new CKEditorError(\"markercollection-refresh-marker-not-exists\", this);\n\t\tconst range = marker.getRange();\n\t\tthis.fire(`update:${markerName}`, marker, range, range, marker.getData());\n\t}\n\t/**\n\t* Returns iterator that iterates over all markers, which ranges\n\t* contain given {@link module:engine/model/position~ModelPosition position}.\n\t*/\n\t*getMarkersAtPosition(position) {\n\t\tfor (const marker of this) if (marker.getRange().containsPosition(position)) yield marker;\n\t}\n\t/**\n\t* Returns iterator that iterates over all markers, which intersects with given {@link module:engine/model/range~ModelRange range}.\n\t*/\n\t*getMarkersIntersectingRange(range) {\n\t\tfor (const marker of this) if (marker.getRange().getIntersection(range) !== null) yield marker;\n\t}\n\t/**\n\t* Destroys marker collection and all markers inside it.\n\t*/\n\tdestroy() {\n\t\tfor (const marker of this._markers.values()) this._destroyMarker(marker);\n\t\tthis._markers.clear();\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Iterates over all markers that starts with given `prefix`.\n\t*\n\t* ```ts\n\t* const markerFooA = markersCollection._set( 'foo:a', rangeFooA );\n\t* const markerFooB = markersCollection._set( 'foo:b', rangeFooB );\n\t* const markerBarA = markersCollection._set( 'bar:a', rangeBarA );\n\t* const markerFooBarA = markersCollection._set( 'foobar:a', rangeFooBarA );\n\t* Array.from( markersCollection.getMarkersGroup( 'foo' ) ); // [ markerFooA, markerFooB ]\n\t* Array.from( markersCollection.getMarkersGroup( 'a' ) ); // []\n\t* ```\n\t*/\n\t*getMarkersGroup(prefix) {\n\t\tfor (const marker of this._markers.values()) if (marker.name.startsWith(prefix + \":\")) yield marker;\n\t}\n\t/**\n\t* Destroys the marker.\n\t*/\n\t_destroyMarker(marker) {\n\t\tmarker.stopListening();\n\t\tmarker._detachLiveRange();\n\t}\n};\n/**\n* `Marker` is a continuous part of the model (like a range), is named and represents some kind of information about the\n* marked part of the model document. In contrary to {@link module:engine/model/node~ModelNode nodes}, which are building blocks of\n* the model document tree, markers are not stored directly in the document tree but in the\n* {@link module:engine/model/model~Model#markers model markers' collection}. Still, they are document data, by giving\n* additional meaning to the part of a model document between marker start and marker end.\n*\n* In this sense, markers are similar to adding and converting attributes on nodes. The difference is that attribute is\n* connected with a given node (e.g. a character is bold no matter if it gets moved or content around it changes).\n* Markers on the other hand are continuous ranges and are characterized by their start and end position. This means that\n* any character in the marker is marked by the marker. For example, if a character is moved outside of marker it stops being\n* \"special\" and the marker is shrunk. Similarly, when a character is moved into the marker from other place in document\n* model, it starts being \"special\" and the marker is enlarged.\n*\n* Another upside of markers is that finding marked part of document is fast and easy. Using attributes to mark some nodes\n* and then trying to find that part of document would require traversing whole document tree. Marker gives instant access\n* to the range which it is marking at the moment.\n*\n* Markers are built from a name and a range.\n*\n* Range of the marker is updated automatically when document changes, using\n* {@link module:engine/model/liverange~ModelLiveRange live range} mechanism.\n*\n* Name is used to group and identify markers. Names have to be unique, but markers can be grouped by\n* using common prefixes, separated with `:`, for example: `user:john` or `search:3`. That's useful in term of creating\n* namespaces for custom elements (e.g. comments, highlights). You can use this prefixes in\n* {@link module:engine/model/markercollection~MarkerCollection#event:update} listeners to listen on changes in a group of markers.\n* For instance: `model.markers.on( 'update:user', callback );` will be called whenever any `user:*` markers changes.\n*\n* There are two types of markers.\n*\n* 1. Markers managed directly, without using operations. They are added directly by {@link module:engine/model/writer~ModelWriter}\n* to the {@link module:engine/model/markercollection~MarkerCollection} without any additional mechanism. They can be used\n* as bookmarks or visual markers. They are great for showing results of the find, or select link when the focus is in the input.\n*\n* 1. Markers managed using operations. These markers are also stored in {@link module:engine/model/markercollection~MarkerCollection}\n* but changes in these markers is managed the same way all other changes in the model structure - using operations.\n* Therefore, they are handled in the undo stack and synchronized between clients if the collaboration plugin is enabled.\n* This type of markers is useful for solutions like spell checking or comments.\n*\n* Both type of them should be added / updated by {@link module:engine/model/writer~ModelWriter#addMarker}\n* and removed by {@link module:engine/model/writer~ModelWriter#removeMarker} methods.\n*\n* ```ts\n* model.change( ( writer ) => {\n* \tconst marker = writer.addMarker( name, { range, usingOperation: true } );\n*\n* \t// ...\n*\n* \twriter.removeMarker( marker );\n* } );\n* ```\n*\n* See {@link module:engine/model/writer~ModelWriter} to find more examples.\n*\n* Since markers need to track change in the document, for efficiency reasons, it is best to create and keep as little\n* markers as possible and remove them as soon as they are not needed anymore.\n*\n* Markers can be downcasted and upcasted.\n*\n* Markers downcast happens on {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker} and\n* {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker} events.\n* Use {@link module:engine/conversion/downcasthelpers downcast converters} or attach a custom converter to mentioned events.\n* For {@link module:engine/controller/datacontroller~DataController data pipeline}, marker should be downcasted to an element.\n* Then, it can be upcasted back to a marker. Again, use {@link module:engine/conversion/upcasthelpers upcast converters} or\n* attach a custom converter to {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element}.\n*\n* `Marker` instances are created and destroyed only by {@link ~MarkerCollection MarkerCollection}.\n*/\nvar Marker = class extends MarkerBase {\n\t/**\n\t* Marker's name.\n\t*/\n\tname;\n\t/**\n\t* Flag indicates if the marker is managed using operations or not.\n\t*\n\t* @internal\n\t*/\n\t_managedUsingOperations;\n\t/**\n\t* Specifies whether the marker affects the data produced by the data pipeline\n\t* (is persisted in the editor's data).\n\t*\n\t* @internal\n\t*/\n\t_affectsData;\n\t/**\n\t* Range marked by the marker.\n\t*/\n\t_liveRange;\n\t/**\n\t* Creates a marker instance.\n\t*\n\t* @param name Marker name.\n\t* @param liveRange Range marked by the marker.\n\t* @param managedUsingOperations Specifies whether the marker is managed using operations.\n\t* @param affectsData Specifies whether the marker affects the data produced by the data pipeline (is persisted in the editor's data).\n\t*/\n\tconstructor(name, liveRange, managedUsingOperations, affectsData) {\n\t\tsuper();\n\t\tthis.name = name;\n\t\tthis._liveRange = this._attachLiveRange(liveRange);\n\t\tthis._managedUsingOperations = managedUsingOperations;\n\t\tthis._affectsData = affectsData;\n\t}\n\t/**\n\t* A value indicating if the marker is managed using operations.\n\t* See {@link ~Marker marker class description} to learn more about marker types.\n\t* See {@link module:engine/model/writer~ModelWriter#addMarker}.\n\t*/\n\tget managedUsingOperations() {\n\t\tif (!this._liveRange) throw new CKEditorError(\"marker-destroyed\", this);\n\t\treturn this._managedUsingOperations;\n\t}\n\t/**\n\t* A value indicating if the marker changes the data.\n\t*/\n\tget affectsData() {\n\t\tif (!this._liveRange) throw new CKEditorError(\"marker-destroyed\", this);\n\t\treturn this._affectsData;\n\t}\n\t/**\n\t* Returns the marker data (properties defining the marker).\n\t*/\n\tgetData() {\n\t\treturn {\n\t\t\trange: this.getRange(),\n\t\t\taffectsData: this.affectsData,\n\t\t\tmanagedUsingOperations: this.managedUsingOperations\n\t\t};\n\t}\n\t/**\n\t* Returns current marker start position.\n\t*/\n\tgetStart() {\n\t\tif (!this._liveRange) throw new CKEditorError(\"marker-destroyed\", this);\n\t\treturn this._liveRange.start.clone();\n\t}\n\t/**\n\t* Returns current marker end position.\n\t*/\n\tgetEnd() {\n\t\tif (!this._liveRange) throw new CKEditorError(\"marker-destroyed\", this);\n\t\treturn this._liveRange.end.clone();\n\t}\n\t/**\n\t* Returns a range that represents the current state of the marker.\n\t*\n\t* Keep in mind that returned value is a {@link module:engine/model/range~ModelRange Range}, not a\n\t* {@link module:engine/model/liverange~ModelLiveRange ModelLiveRange}. This means that it is up-to-date and relevant only\n\t* until next model document change. Do not store values returned by this method. Instead, store {@link ~Marker#name}\n\t* and get `Marker` instance from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection} every\n\t* time there is a need to read marker properties. This will guarantee that the marker has not been removed and\n\t* that it's data is up-to-date.\n\t*/\n\tgetRange() {\n\t\tif (!this._liveRange) throw new CKEditorError(\"marker-destroyed\", this);\n\t\treturn this._liveRange.toRange();\n\t}\n\t/**\n\t* Converts `Marker` to plain object and returns it.\n\t*\n\t* @returns `Marker` converted to plain object.\n\t*/\n\ttoJSON() {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\trange: this._liveRange?.toJSON(),\n\t\t\tusingOperations: this._managedUsingOperations,\n\t\t\taffectsData: this._affectsData\n\t\t};\n\t}\n\t/**\n\t* Binds new live range to the marker and detach the old one if is attached.\n\t*\n\t* @internal\n\t* @param liveRange Live range to attach\n\t* @returns Attached live range.\n\t*/\n\t_attachLiveRange(liveRange) {\n\t\tif (this._liveRange) this._detachLiveRange();\n\t\tliveRange.delegate(\"change:range\").to(this);\n\t\tliveRange.delegate(\"change:content\").to(this);\n\t\tthis._liveRange = liveRange;\n\t\treturn liveRange;\n\t}\n\t/**\n\t* Unbinds and destroys currently attached live range.\n\t*\n\t* @internal\n\t*/\n\t_detachLiveRange() {\n\t\tthis._liveRange.stopDelegating(\"change:range\", this);\n\t\tthis._liveRange.stopDelegating(\"change:content\", this);\n\t\tthis._liveRange.detach();\n\t\tthis._liveRange = null;\n\t}\n};\nMarker.prototype.is = function(type) {\n\treturn type === \"marker\" || type === \"model:marker\";\n};\n/**\n* Cannot use a {@link module:engine/model/markercollection~MarkerCollection#destroy destroyed marker} instance.\n*\n* @error marker-destroyed\n*/\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/operation/detachoperation\n*/\n/**\n* Operation to permanently remove node from detached root.\n* Note this operation is only a local operation and won't be send to the other clients.\n*\n* @internal\n*/\nvar DetachOperation = class extends Operation {\n\t/**\n\t* Position before the first {@link module:engine/model/item~ModelItem model item} to detach.\n\t*/\n\tsourcePosition;\n\t/**\n\t* Offset size of moved range.\n\t*/\n\thowMany;\n\t/**\n\t* Creates an insert operation.\n\t*\n\t* @param sourcePosition Position before the first {@link module:engine/model/item~ModelItem model item} to move.\n\t* @param howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at\n\t* `sourcePosition` with offset shifted by `howMany`.\n\t*/\n\tconstructor(sourcePosition, howMany) {\n\t\tsuper(null);\n\t\tthis.sourcePosition = sourcePosition.clone();\n\t\tthis.howMany = howMany;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget type() {\n\t\treturn \"detach\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tget affectedSelectable() {\n\t\treturn null;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\t\tjson.sourcePosition = this.sourcePosition.toJSON();\n\t\treturn json;\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_validate() {\n\t\tif (this.sourcePosition.root.document)\n /**\n\t\t* Cannot detach document node.\n\t\t*\n\t\t* @error detach-operation-on-document-node\n\t\t*/\n\t\tthrow new CKEditorError(\"detach-operation-on-document-node\", this);\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\t_execute() {\n\t\t_remove(ModelRange._createFromPositionAndShift(this.sourcePosition, this.howMany));\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get className() {\n\t\treturn \"DetachOperation\";\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/documentfragment\n*/\n/**\n* ModelDocumentFragment represents a part of model which does not have a common root but its top-level nodes\n* can be seen as siblings. In other words, it is a detached part of model tree, without a root.\n*\n* ModelDocumentFragment has own {@link module:engine/model/markercollection~MarkerCollection}. Markers from this collection\n* will be set to the {@link module:engine/model/model~Model#markers model markers} by a\n* {@link module:engine/model/writer~ModelWriter#insert} function.\n*/\nvar ModelDocumentFragment = class ModelDocumentFragment extends ModelTypeCheckable {\n\t/**\n\t* ModelDocumentFragment static markers map. This is a list of names and {@link module:engine/model/range~ModelRange ranges}\n\t* which will be set as Markers to {@link module:engine/model/model~Model#markers model markers collection}\n\t* when ModelDocumentFragment will be inserted to the document.\n\t*/\n\tmarkers = /* @__PURE__ */ new Map();\n\t/**\n\t* List of nodes contained inside the document fragment.\n\t*/\n\t_children = new ModelNodeList();\n\t/**\n\t* Creates an empty `ModelDocumentFragment`.\n\t*\n\t* **Note:** Constructor of this class shouldn't be used directly in the code.\n\t* Use the {@link module:engine/model/writer~ModelWriter#createDocumentFragment} method instead.\n\t*\n\t* @internal\n\t* @param children Nodes to be contained inside the `ModelDocumentFragment`.\n\t*/\n\tconstructor(children) {\n\t\tsuper();\n\t\tif (children) this._insertChild(0, children);\n\t}\n\t/**\n\t* Returns an iterator that iterates over all nodes contained inside this document fragment.\n\t*/\n\t[Symbol.iterator]() {\n\t\treturn this.getChildren();\n\t}\n\t/**\n\t* Number of this document fragment's children.\n\t*/\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\t/**\n\t* Sum of {@link module:engine/model/node~ModelNode#offsetSize offset sizes} of all of this document fragment's children.\n\t*/\n\tget maxOffset() {\n\t\treturn this._children.maxOffset;\n\t}\n\t/**\n\t* Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t*/\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\t/**\n\t* Artificial next sibling. Returns `null`. Added for compatibility reasons.\n\t*/\n\tget nextSibling() {\n\t\treturn null;\n\t}\n\t/**\n\t* Artificial previous sibling. Returns `null`. Added for compatibility reasons.\n\t*/\n\tget previousSibling() {\n\t\treturn null;\n\t}\n\t/**\n\t* Artificial root of `ModelDocumentFragment`. Returns itself. Added for compatibility reasons.\n\t*/\n\tget root() {\n\t\treturn this;\n\t}\n\t/**\n\t* Artificial parent of `ModelDocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t*/\n\tget parent() {\n\t\treturn null;\n\t}\n\t/**\n\t* Artificial owner of `ModelDocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t*/\n\tget document() {\n\t\treturn null;\n\t}\n\t/**\n\t* Returns `false` as `ModelDocumentFragment` by definition is not attached to a document. Added for compatibility reasons.\n\t*/\n\tisAttached() {\n\t\treturn false;\n\t}\n\t/**\n\t* Returns empty array. Added for compatibility reasons.\n\t*/\n\tgetAncestors() {\n\t\treturn [];\n\t}\n\t/**\n\t* Gets the child at the given index. Returns `null` if incorrect index was passed.\n\t*\n\t* @param index Index in this document fragment.\n\t* @returns Child node.\n\t*/\n\tgetChild(index) {\n\t\treturn this._children.getNode(index);\n\t}\n\t/**\n\t* Gets the child at the given offset. Returns `null` if incorrect index was passed.\n\t*\n\t* @param offset Offset in this document fragment.\n\t* @returns Child node.\n\t*/\n\tgetChildAtOffset(offset) {\n\t\treturn this._children.getNodeAtOffset(offset);\n\t}\n\t/**\n\t* Returns an iterator that iterates over all of this document fragment's children.\n\t*/\n\tgetChildren() {\n\t\treturn this._children[Symbol.iterator]();\n\t}\n\t/**\n\t* Returns an index of the given child node. Returns `null` if given node is not a child of this document fragment.\n\t*\n\t* @param node Child node to look for.\n\t* @returns Child node's index.\n\t*/\n\tgetChildIndex(node) {\n\t\treturn this._children.getNodeIndex(node);\n\t}\n\t/**\n\t* Returns the starting offset of given child. Starting offset is equal to the sum of\n\t* {@link module:engine/model/node~ModelNode#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if\n\t* given node is not a child of this document fragment.\n\t*\n\t* @param node Child node to look for.\n\t* @returns Child node's starting offset.\n\t*/\n\tgetChildStartOffset(node) {\n\t\treturn this._children.getNodeStartOffset(node);\n\t}\n\t/**\n\t* Returns path to a `ModelDocumentFragment`, which is an empty array. Added for compatibility reasons.\n\t*/\n\tgetPath() {\n\t\treturn [];\n\t}\n\t/**\n\t* Returns a descendant node by its path relative to this element.\n\t*\n\t* ```ts\n\t* // <this>a<b>c</b></this>\n\t* this.getNodeByPath( [ 0 ] ); // -> \"a\"\n\t* this.getNodeByPath( [ 1 ] ); // -> <b>\n\t* this.getNodeByPath( [ 1, 0 ] ); // -> \"c\"\n\t* ```\n\t*\n\t* @param relativePath Path of the node to find, relative to this element.\n\t*/\n\tgetNodeByPath(relativePath) {\n\t\tlet node = this;\n\t\tfor (const offset of relativePath) node = node.getChildAtOffset(offset);\n\t\treturn node;\n\t}\n\t/**\n\t* Converts offset \"position\" to index \"position\".\n\t*\n\t* Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is\n\t* too high, returns index after last child.\n\t*\n\t* ```ts\n\t* const textNode = new Text( 'foo' );\n\t* const pElement = new Element( 'p' );\n\t* const docFrag = new ModelDocumentFragment( [ textNode, pElement ] );\n\t* docFrag.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t* docFrag.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t* docFrag.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t* docFrag.offsetToIndex( 2 ); // Returns 0.\n\t* docFrag.offsetToIndex( 3 ); // Returns 1.\n\t* docFrag.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t* ```\n\t*\n\t* @param offset Offset to look for.\n\t* @returns Index of a node that occupies given offset.\n\t*/\n\toffsetToIndex(offset) {\n\t\treturn this._children.offsetToIndex(offset);\n\t}\n\t/**\n\t* Converts `ModelDocumentFragment` instance to plain object and returns it.\n\t* Takes care of converting all of this document fragment's children.\n\t*\n\t* @returns `ModelDocumentFragment` instance converted to plain object.\n\t*/\n\ttoJSON() {\n\t\tconst json = [];\n\t\tfor (const node of this._children) json.push(node.toJSON());\n\t\treturn json;\n\t}\n\t/**\n\t* Creates a `ModelDocumentFragment` instance from given plain object (i.e. parsed JSON string).\n\t* Converts `ModelDocumentFragment` children to proper nodes.\n\t*\n\t* @param json Plain object to be converted to `ModelDocumentFragment`.\n\t* @returns `ModelDocumentFragment` instance created using given plain object.\n\t*/\n\tstatic fromJSON(json) {\n\t\tconst children = [];\n\t\tfor (const child of json) if (child.name) children.push(ModelElement.fromJSON(child));\n\t\telse children.push(ModelText.fromJSON(child));\n\t\treturn new ModelDocumentFragment(children);\n\t}\n\t/**\n\t* {@link #_insertChild Inserts} one or more nodes at the end of this document fragment.\n\t*\n\t* @internal\n\t* @param items Items to be inserted.\n\t*/\n\t_appendChild(items) {\n\t\tthis._insertChild(this.childCount, items);\n\t}\n\t/**\n\t* Inserts one or more nodes at the given index and sets {@link module:engine/model/node~ModelNode#parent parent} of these nodes\n\t* to this document fragment.\n\t*\n\t* @internal\n\t* @param index Index at which nodes should be inserted.\n\t* @param items Items to be inserted.\n\t*/\n\t_insertChild(index, items) {\n\t\tconst nodes = normalize(items);\n\t\tfor (const node of nodes) {\n\t\t\tif (node.parent !== null) node._remove();\n\t\t\tnode.parent = this;\n\t\t}\n\t\tthis._children._insertNodes(index, nodes);\n\t}\n\t/**\n\t* Removes one or more nodes starting at the given index\n\t* and sets {@link module:engine/model/node~ModelNode#parent parent} of these nodes to `null`.\n\t*\n\t* @internal\n\t* @param index Index of the first node to remove.\n\t* @param howMany Number of nodes to remove.\n\t* @returns Array containing removed nodes.\n\t*/\n\t_removeChildren(index, howMany = 1) {\n\t\tconst nodes = this._children._removeNodes(index, howMany);\n\t\tfor (const node of nodes) node.parent = null;\n\t\treturn nodes;\n\t}\n\t/**\n\t* Removes children nodes provided as an array and sets\n\t* the {@link module:engine/model/node~ModelNode#parent parent} of these nodes to `null`.\n\t*\n\t* These nodes do not need to be direct siblings.\n\t*\n\t* This method is faster than removing nodes one by one, as it recalculates offsets only once.\n\t*\n\t* @internal\n\t* @param nodes Array of nodes.\n\t*/\n\t_removeChildrenArray(nodes) {\n\t\tthis._children._removeNodesArray(nodes);\n\t\tfor (const node of nodes) node.parent = null;\n\t}\n};\nModelDocumentFragment.prototype.is = function(type) {\n\treturn type === \"documentFragment\" || type === \"model:documentFragment\";\n};\n/**\n* Converts strings to Text and non-iterables to arrays.\n*/\nfunction normalize(nodes) {\n\tif (typeof nodes == \"string\") return [new ModelText(nodes)];\n\tif (!isIterable(nodes)) nodes = [nodes];\n\treturn Array.from(nodes).map((node) => {\n\t\tif (typeof node == \"string\") return new ModelText(node);\n\t\tif (node instanceof ModelTextProxy) return new ModelText(node.data, node.getAttributes());\n\t\treturn node;\n\t});\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/writer\n*/\n/**\n* The model can only be modified by using the writer. It should be used whenever you want to create a node, modify\n* child nodes, attributes or text, set the selection's position and its attributes.\n*\n* The instance of the writer is only available in the {@link module:engine/model/model~Model#change `change()`} or\n* {@link module:engine/model/model~Model#enqueueChange `enqueueChange()`}.\n*\n* ```ts\n* model.change( writer => {\n* \twriter.insertText( 'foo', paragraph, 'end' );\n* } );\n* ```\n*\n* Note that the writer should never be stored and used outside of the `change()` and\n* `enqueueChange()` blocks.\n*\n* Note that writer's methods do not check the {@link module:engine/model/schema~ModelSchema}. It is possible\n* to create incorrect model structures by using the writer. Read more about in\n* {@glink framework/deep-dive/schema#who-checks-the-schema \"Who checks the schema?\"}.\n*\n* @see module:engine/model/model~Model#change\n* @see module:engine/model/model~Model#enqueueChange\n*/\nvar ModelWriter = class {\n\t/**\n\t* Instance of the model on which this writer operates.\n\t*/\n\tmodel;\n\t/**\n\t* The batch to which this writer will add changes.\n\t*/\n\tbatch;\n\t/**\n\t* Creates a writer instance.\n\t*\n\t* **Note:** It is not recommended to use it directly. Use {@link module:engine/model/model~Model#change `Model#change()`} or\n\t* {@link module:engine/model/model~Model#enqueueChange `Model#enqueueChange()`} instead.\n\t*\n\t* @internal\n\t*/\n\tconstructor(model, batch) {\n\t\tthis.model = model;\n\t\tthis.batch = batch;\n\t}\n\t/**\n\t* Creates a new {@link module:engine/model/text~ModelText text node}.\n\t*\n\t* ```ts\n\t* writer.createText( 'foo' );\n\t* writer.createText( 'foo', { bold: true } );\n\t* ```\n\t*\n\t* @param data Text data.\n\t* @param attributes Text attributes.\n\t* @returns {module:engine/model/text~ModelText} Created text node.\n\t*/\n\tcreateText(data, attributes) {\n\t\treturn new ModelText(data, attributes);\n\t}\n\t/**\n\t* Creates a new {@link module:engine/model/element~ModelElement element}.\n\t*\n\t* ```ts\n\t* writer.createElement( 'paragraph' );\n\t* writer.createElement( 'paragraph', { alignment: 'center' } );\n\t* ```\n\t*\n\t* @param name Name of the element.\n\t* @param attributes Elements attributes.\n\t* @returns Created element.\n\t*/\n\tcreateElement(name, attributes) {\n\t\treturn new ModelElement(name, attributes);\n\t}\n\t/**\n\t* Creates a new {@link module:engine/model/documentfragment~ModelDocumentFragment document fragment}.\n\t*\n\t* @returns Created document fragment.\n\t*/\n\tcreateDocumentFragment() {\n\t\treturn new ModelDocumentFragment();\n\t}\n\t/**\n\t* Creates a copy of the element and returns it. Created element has the same name and attributes as the original element.\n\t* If clone is deep, the original element's children are also cloned. If not, then empty element is returned.\n\t*\n\t* @param element The element to clone.\n\t* @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t* element will be cloned without any child.\n\t*/\n\tcloneElement(element, deep = true) {\n\t\treturn element._clone(deep);\n\t}\n\t/**\n\t* Inserts item on given position.\n\t*\n\t* ```ts\n\t* const paragraph = writer.createElement( 'paragraph' );\n\t* writer.insert( paragraph, position );\n\t* ```\n\t*\n\t* Instead of using position you can use parent and offset:\n\t*\n\t* ```ts\n\t* const text = writer.createText( 'foo' );\n\t* writer.insert( text, paragraph, 5 );\n\t* ```\n\t*\n\t* You can also use `end` instead of the offset to insert at the end:\n\t*\n\t* ```ts\n\t* const text = writer.createText( 'foo' );\n\t* writer.insert( text, paragraph, 'end' );\n\t* ```\n\t*\n\t* Or insert before or after another element:\n\t*\n\t* ```ts\n\t* const paragraph = writer.createElement( 'paragraph' );\n\t* writer.insert( paragraph, anotherParagraph, 'after' );\n\t* ```\n\t*\n\t* These parameters works the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t*\n\t* Note that if the item already has parent it will be removed from the previous parent.\n\t*\n\t* Note that you cannot re-insert a node from a document to a different document or a document fragment. In this case,\n\t* `model-writer-insert-forbidden-move` is thrown.\n\t*\n\t* If you want to move {@link module:engine/model/range~ModelRange range} instead of an\n\t* {@link module:engine/model/item~ModelItem item} use {@link module:engine/model/writer~ModelWriter#move `Writer#move()`}.\n\t*\n\t* **Note:** For a paste-like content insertion mechanism see\n\t* {@link module:engine/model/model~Model#insertContent `model.insertContent()`}.\n\t*\n\t* @param item Item or document fragment to insert.\n\t* @param offset Offset or one of the flags. Used only when second parameter is a {@link module:engine/model/item~ModelItem model item}.\n\t*/\n\tinsert(item, itemOrPosition, offset = 0) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (item instanceof ModelText && item.data == \"\") return;\n\t\tconst position = ModelPosition._createAt(itemOrPosition, offset);\n\t\tif (item.parent) if (isSameTree(item.root, position.root)) {\n\t\t\tthis.move(ModelRange._createOn(item), position);\n\t\t\treturn;\n\t\t} else if (item.root.document)\n /**\n\t\t* Cannot move a node from a document to a different tree.\n\t\t* It is forbidden to move a node that was already in a document outside of it.\n\t\t*\n\t\t* @error model-writer-insert-forbidden-move\n\t\t*/\n\t\tthrow new CKEditorError(\"model-writer-insert-forbidden-move\", this);\n\t\telse this.remove(item);\n\t\tconst version = position.root.document ? position.root.document.version : null;\n\t\tconst children = item instanceof ModelDocumentFragment ? item._removeChildren(0, item.childCount) : item;\n\t\tconst insert = new InsertOperation(position, children, version);\n\t\tif (item instanceof ModelText) insert.shouldReceiveAttributes = true;\n\t\tthis.batch.addOperation(insert);\n\t\tthis.model.applyOperation(insert);\n\t\tif (item instanceof ModelDocumentFragment) for (const [markerName, markerRange] of item.markers) {\n\t\t\tconst rangeRootPosition = ModelPosition._createAt(markerRange.root, 0);\n\t\t\tconst options = {\n\t\t\t\trange: new ModelRange(markerRange.start._getCombined(rangeRootPosition, position), markerRange.end._getCombined(rangeRootPosition, position)),\n\t\t\t\tusingOperation: true,\n\t\t\t\taffectsData: true\n\t\t\t};\n\t\t\tif (this.model.markers.has(markerName)) this.updateMarker(markerName, options);\n\t\t\telse this.addMarker(markerName, options);\n\t\t}\n\t}\n\tinsertText(text, attributes, itemOrPosition, offset) {\n\t\tif (attributes instanceof ModelDocumentFragment || attributes instanceof ModelElement || attributes instanceof ModelPosition) this.insert(this.createText(text), attributes, itemOrPosition);\n\t\telse this.insert(this.createText(text, attributes), itemOrPosition, offset);\n\t}\n\tinsertElement(name, attributes, itemOrPositionOrOffset, offset) {\n\t\tif (attributes instanceof ModelDocumentFragment || attributes instanceof ModelElement || attributes instanceof ModelPosition) this.insert(this.createElement(name), attributes, itemOrPositionOrOffset);\n\t\telse this.insert(this.createElement(name, attributes), itemOrPositionOrOffset, offset);\n\t}\n\t/**\n\t* Inserts item at the end of the given parent.\n\t*\n\t* ```ts\n\t* const paragraph = writer.createElement( 'paragraph' );\n\t* writer.append( paragraph, root );\n\t* ```\n\t*\n\t* Note that if the item already has parent it will be removed from the previous parent.\n\t*\n\t* If you want to move {@link module:engine/model/range~ModelRange range} instead of an\n\t* {@link module:engine/model/item~ModelItem item} use {@link module:engine/model/writer~ModelWriter#move `Writer#move()`}.\n\t*\n\t* @param item Item or document fragment to insert.\n\t*/\n\tappend(item, parent) {\n\t\tthis.insert(item, parent, \"end\");\n\t}\n\tappendText(text, attributes, parent) {\n\t\tif (attributes instanceof ModelDocumentFragment || attributes instanceof ModelElement) this.insert(this.createText(text), attributes, \"end\");\n\t\telse this.insert(this.createText(text, attributes), parent, \"end\");\n\t}\n\tappendElement(name, attributes, parent) {\n\t\tif (attributes instanceof ModelDocumentFragment || attributes instanceof ModelElement) this.insert(this.createElement(name), attributes, \"end\");\n\t\telse this.insert(this.createElement(name, attributes), parent, \"end\");\n\t}\n\t/**\n\t* Sets value of the attribute with given key on a {@link module:engine/model/item~ModelItem model item}\n\t* or on a {@link module:engine/model/range~ModelRange range}.\n\t*\n\t* @param key Attribute key.\n\t* @param value Attribute new value.\n\t* @param itemOrRange Model item or range on which the attribute will be set.\n\t*/\n\tsetAttribute(key, value, itemOrRange) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (itemOrRange instanceof ModelRange) {\n\t\t\tconst ranges = itemOrRange.getMinimalFlatRanges();\n\t\t\tfor (const range of ranges) setAttributeOnRange(this, key, value, range);\n\t\t} else setAttributeOnItem(this, key, value, itemOrRange);\n\t}\n\t/**\n\t* Sets values of attributes on a {@link module:engine/model/item~ModelItem model item}\n\t* or on a {@link module:engine/model/range~ModelRange range}.\n\t*\n\t* ```ts\n\t* writer.setAttributes( {\n\t* \tbold: true,\n\t* \titalic: true\n\t* }, range );\n\t* ```\n\t*\n\t* @param attributes Attributes keys and values.\n\t* @param itemOrRange Model item or range on which the attributes will be set.\n\t*/\n\tsetAttributes(attributes, itemOrRange) {\n\t\tfor (const [key, val] of toMap(attributes)) this.setAttribute(key, val, itemOrRange);\n\t}\n\t/**\n\t* Removes an attribute with given key from a {@link module:engine/model/item~ModelItem model item}\n\t* or from a {@link module:engine/model/range~ModelRange range}.\n\t*\n\t* @param key Attribute key.\n\t* @param itemOrRange Model item or range from which the attribute will be removed.\n\t*/\n\tremoveAttribute(key, itemOrRange) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (itemOrRange instanceof ModelRange) {\n\t\t\tconst ranges = itemOrRange.getMinimalFlatRanges();\n\t\t\tfor (const range of ranges) setAttributeOnRange(this, key, null, range);\n\t\t} else setAttributeOnItem(this, key, null, itemOrRange);\n\t}\n\t/**\n\t* Removes all attributes from all elements in the range or from the given item.\n\t*\n\t* @param itemOrRange Model item or range from which all attributes will be removed.\n\t*/\n\tclearAttributes(itemOrRange) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tconst removeAttributesFromItem = (item) => {\n\t\t\tfor (const attribute of item.getAttributeKeys()) this.removeAttribute(attribute, item);\n\t\t};\n\t\tif (!(itemOrRange instanceof ModelRange)) removeAttributesFromItem(itemOrRange);\n\t\telse for (const item of itemOrRange.getItems()) removeAttributesFromItem(item);\n\t}\n\t/**\n\t* Moves all items in the source range to the target position.\n\t*\n\t* ```ts\n\t* writer.move( sourceRange, targetPosition );\n\t* ```\n\t*\n\t* Instead of the target position you can use parent and offset or define that range should be moved to the end\n\t* or before or after chosen item:\n\t*\n\t* ```ts\n\t* // Moves all items in the range to the paragraph at offset 5:\n\t* writer.move( sourceRange, paragraph, 5 );\n\t* // Moves all items in the range to the end of a blockquote:\n\t* writer.move( sourceRange, blockquote, 'end' );\n\t* // Moves all items in the range to a position after an image:\n\t* writer.move( sourceRange, image, 'after' );\n\t* ```\n\t*\n\t* These parameters work the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t*\n\t* Note that items can be moved only within the same tree. It means that you can move items within the same root\n\t* (element or document fragment) or between {@link module:engine/model/document~ModelDocument#roots documents roots},\n\t* but you cannot move items from document fragment to the document or from one detached element to another. Use\n\t* {@link module:engine/model/writer~ModelWriter#insert} in such cases.\n\t*\n\t* @param range Source range.\n\t* @param offset Offset or one of the flags. Used only when second parameter is a {@link module:engine/model/item~ModelItem model item}.\n\t*/\n\tmove(range, itemOrPosition, offset) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (!(range instanceof ModelRange))\n /**\n\t\t* Invalid range to move.\n\t\t*\n\t\t* @error writer-move-invalid-range\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-move-invalid-range\", this);\n\t\tif (!range.isFlat)\n /**\n\t\t* Range to move is not flat.\n\t\t*\n\t\t* @error writer-move-range-not-flat\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-move-range-not-flat\", this);\n\t\tconst position = ModelPosition._createAt(itemOrPosition, offset);\n\t\tif (position.isEqual(range.start)) return;\n\t\tthis._addOperationForAffectedMarkers(\"move\", range);\n\t\tif (!isSameTree(range.root, position.root))\n /**\n\t\t* Range is going to be moved within not the same document. Please use\n\t\t* {@link module:engine/model/writer~ModelWriter#insert insert} instead.\n\t\t*\n\t\t* @error writer-move-different-document\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-move-different-document\", this);\n\t\tconst version = range.root.document ? range.root.document.version : null;\n\t\tconst operation = new MoveOperation(range.start, range.end.offset - range.start.offset, position, version);\n\t\tthis.batch.addOperation(operation);\n\t\tthis.model.applyOperation(operation);\n\t}\n\t/**\n\t* Removes given model {@link module:engine/model/item~ModelItem item} or {@link module:engine/model/range~ModelRange range}.\n\t*\n\t* @param itemOrRange Model item or range to remove.\n\t*/\n\tremove(itemOrRange) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tconst ranges = (itemOrRange instanceof ModelRange ? itemOrRange : ModelRange._createOn(itemOrRange)).getMinimalFlatRanges().reverse();\n\t\tfor (const flat of ranges) {\n\t\t\tthis._addOperationForAffectedMarkers(\"move\", flat);\n\t\t\tapplyRemoveOperation(flat.start, flat.end.offset - flat.start.offset, this.batch, this.model);\n\t\t}\n\t}\n\t/**\n\t* Merges two siblings at the given position.\n\t*\n\t* Node before and after the position have to be an element. Otherwise `writer-merge-no-element-before` or\n\t* `writer-merge-no-element-after` error will be thrown.\n\t*\n\t* @param position Position between merged elements.\n\t*/\n\tmerge(position) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tconst nodeBefore = position.nodeBefore;\n\t\tconst nodeAfter = position.nodeAfter;\n\t\tthis._addOperationForAffectedMarkers(\"merge\", position);\n\t\tif (!(nodeBefore instanceof ModelElement))\n /**\n\t\t* Node before merge position must be an element.\n\t\t*\n\t\t* @error writer-merge-no-element-before\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-merge-no-element-before\", this);\n\t\tif (!(nodeAfter instanceof ModelElement))\n /**\n\t\t* Node after merge position must be an element.\n\t\t*\n\t\t* @error writer-merge-no-element-after\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-merge-no-element-after\", this);\n\t\tif (!position.root.document) this._mergeDetached(position);\n\t\telse this._merge(position);\n\t}\n\t/**\n\t* Shortcut for {@link module:engine/model/model~Model#createPositionFromPath `Model#createPositionFromPath()`}.\n\t*\n\t* @param root Root of the position.\n\t* @param path Position path. See {@link module:engine/model/position~ModelPosition#path}.\n\t* @param stickiness Position stickiness. See {@link module:engine/model/position~ModelPositionStickiness}.\n\t*/\n\tcreatePositionFromPath(root, path, stickiness) {\n\t\treturn this.model.createPositionFromPath(root, path, stickiness);\n\t}\n\t/**\n\t* Shortcut for {@link module:engine/model/model~Model#createPositionAt `Model#createPositionAt()`}.\n\t*\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~ModelItem model item}.\n\t*/\n\tcreatePositionAt(itemOrPosition, offset) {\n\t\treturn this.model.createPositionAt(itemOrPosition, offset);\n\t}\n\t/**\n\t* Shortcut for {@link module:engine/model/model~Model#createPositionAfter `Model#createPositionAfter()`}.\n\t*\n\t* @param item Item after which the position should be placed.\n\t*/\n\tcreatePositionAfter(item) {\n\t\treturn this.model.createPositionAfter(item);\n\t}\n\t/**\n\t* Shortcut for {@link module:engine/model/model~Model#createPositionBefore `Model#createPositionBefore()`}.\n\t*\n\t* @param item Item after which the position should be placed.\n\t*/\n\tcreatePositionBefore(item) {\n\t\treturn this.model.createPositionBefore(item);\n\t}\n\t/**\n\t* Shortcut for {@link module:engine/model/model~Model#createRange `Model#createRange()`}.\n\t*\n\t* @param start Start position.\n\t* @param end End position. If not set, range will be collapsed at `start` position.\n\t*/\n\tcreateRange(start, end) {\n\t\treturn this.model.createRange(start, end);\n\t}\n\t/**\n\t* Shortcut for {@link module:engine/model/model~Model#createRangeIn `Model#createRangeIn()`}.\n\t*\n\t* @param element Element which is a parent for the range.\n\t*/\n\tcreateRangeIn(element) {\n\t\treturn this.model.createRangeIn(element);\n\t}\n\t/**\n\t* Shortcut for {@link module:engine/model/model~Model#createRangeOn `Model#createRangeOn()`}.\n\t*\n\t* @param element Element which is a parent for the range.\n\t*/\n\tcreateRangeOn(element) {\n\t\treturn this.model.createRangeOn(element);\n\t}\n\tcreateSelection(...args) {\n\t\treturn this.model.createSelection(...args);\n\t}\n\t/**\n\t* Performs merge action in a detached tree.\n\t*\n\t* @param position Position between merged elements.\n\t*/\n\t_mergeDetached(position) {\n\t\tconst nodeBefore = position.nodeBefore;\n\t\tconst nodeAfter = position.nodeAfter;\n\t\tthis.move(ModelRange._createIn(nodeAfter), ModelPosition._createAt(nodeBefore, \"end\"));\n\t\tthis.remove(nodeAfter);\n\t}\n\t/**\n\t* Performs merge action in a non-detached tree.\n\t*\n\t* @param position Position between merged elements.\n\t*/\n\t_merge(position) {\n\t\tconst targetPosition = ModelPosition._createAt(position.nodeBefore, \"end\");\n\t\tconst sourcePosition = ModelPosition._createAt(position.nodeAfter, 0);\n\t\tconst graveyard = position.root.document.graveyard;\n\t\tconst graveyardPosition = new ModelPosition(graveyard, [0]);\n\t\tconst version = position.root.document.version;\n\t\tconst merge = new MergeOperation(sourcePosition, position.nodeAfter.maxOffset, targetPosition, graveyardPosition, version);\n\t\tthis.batch.addOperation(merge);\n\t\tthis.model.applyOperation(merge);\n\t}\n\t/**\n\t* Renames the given element.\n\t*\n\t* @param element The element to rename.\n\t* @param newName New element name.\n\t*/\n\trename(element, newName) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (!(element instanceof ModelElement))\n /**\n\t\t* Trying to rename an object which is not an instance of Element.\n\t\t*\n\t\t* @error writer-rename-not-element-instance\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-rename-not-element-instance\", this);\n\t\tconst version = element.root.document ? element.root.document.version : null;\n\t\tconst renameOperation = new RenameOperation(ModelPosition._createBefore(element), element.name, newName, version);\n\t\tthis.batch.addOperation(renameOperation);\n\t\tthis.model.applyOperation(renameOperation);\n\t}\n\t/**\n\t* Splits elements starting from the given position and going to the top of the model tree as long as given\n\t* `limitElement` is reached. When `limitElement` is not defined then only the parent of the given position will be split.\n\t*\n\t* The element needs to have a parent. It cannot be a root element nor a document fragment.\n\t* The `writer-split-element-no-parent` error will be thrown if you try to split an element with no parent.\n\t*\n\t* @param position Position of split.\n\t* @param limitElement Stop splitting when this element will be reached.\n\t* @returns Split result with properties:\n\t* * `position` - Position between split elements.\n\t* * `range` - Range that stars from the end of the first split element and ends at the beginning of the first copy element.\n\t*/\n\tsplit(position, limitElement) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tlet splitElement = position.parent;\n\t\tif (!splitElement.parent)\n /**\n\t\t* Element with no parent cannot be split.\n\t\t*\n\t\t* @error writer-split-element-no-parent\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-split-element-no-parent\", this);\n\t\tif (!limitElement) limitElement = splitElement.parent;\n\t\tif (!position.parent.getAncestors({ includeSelf: true }).includes(limitElement))\n /**\n\t\t* Limit element is not a position ancestor.\n\t\t*\n\t\t* @error writer-split-invalid-limit-element\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-split-invalid-limit-element\", this);\n\t\tlet firstSplitElement;\n\t\tlet firstCopyElement;\n\t\tdo {\n\t\t\tconst version = splitElement.root.document ? splitElement.root.document.version : null;\n\t\t\tconst howMany = splitElement.maxOffset - position.offset;\n\t\t\tconst insertionPosition = SplitOperation.getInsertionPosition(position);\n\t\t\tconst split = new SplitOperation(position, howMany, insertionPosition, null, version);\n\t\t\tthis.batch.addOperation(split);\n\t\t\tthis.model.applyOperation(split);\n\t\t\tif (!firstSplitElement && !firstCopyElement) {\n\t\t\t\tfirstSplitElement = splitElement;\n\t\t\t\tfirstCopyElement = position.parent.nextSibling;\n\t\t\t}\n\t\t\tposition = this.createPositionAfter(position.parent);\n\t\t\tsplitElement = position.parent;\n\t\t} while (splitElement !== limitElement);\n\t\treturn {\n\t\t\tposition,\n\t\t\trange: new ModelRange(ModelPosition._createAt(firstSplitElement, \"end\"), ModelPosition._createAt(firstCopyElement, 0))\n\t\t};\n\t}\n\t/**\n\t* Wraps the given range with the given element or with a new element (if a string was passed).\n\t*\n\t* **Note:** range to wrap should be a \"flat range\" (see {@link module:engine/model/range~ModelRange#isFlat `Range#isFlat`}).\n\t* If not, an error will be thrown.\n\t*\n\t* @param range Range to wrap.\n\t* @param elementOrString Element or name of element to wrap the range with.\n\t*/\n\twrap(range, elementOrString) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (!range.isFlat)\n /**\n\t\t* Range to wrap is not flat.\n\t\t*\n\t\t* @error writer-wrap-range-not-flat\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-wrap-range-not-flat\", this);\n\t\tconst element = elementOrString instanceof ModelElement ? elementOrString : new ModelElement(elementOrString);\n\t\tif (element.childCount > 0)\n /**\n\t\t* Element to wrap with is not empty.\n\t\t*\n\t\t* @error writer-wrap-element-not-empty\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-wrap-element-not-empty\", this);\n\t\tif (element.parent !== null)\n /**\n\t\t* Element to wrap with is already attached to a tree model.\n\t\t*\n\t\t* @error writer-wrap-element-attached\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-wrap-element-attached\", this);\n\t\tthis.insert(element, range.start);\n\t\tconst shiftedRange = new ModelRange(range.start.getShiftedBy(1), range.end.getShiftedBy(1));\n\t\tthis.move(shiftedRange, ModelPosition._createAt(element, 0));\n\t}\n\t/**\n\t* Unwraps children of the given element – all its children are moved before it and then the element is removed.\n\t* Throws error if you try to unwrap an element which does not have a parent.\n\t*\n\t* @param element Element to unwrap.\n\t*/\n\tunwrap(element) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (element.parent === null)\n /**\n\t\t* Trying to unwrap an element which has no parent.\n\t\t*\n\t\t* @error writer-unwrap-element-no-parent\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-unwrap-element-no-parent\", this);\n\t\tthis.move(ModelRange._createIn(element), this.createPositionAfter(element));\n\t\tthis.remove(element);\n\t}\n\t/**\n\t* Adds a {@link module:engine/model/markercollection~Marker marker}. Marker is a named range, which tracks\n\t* changes in the document and updates its range automatically, when model tree changes.\n\t*\n\t* As the first parameter you can set marker name.\n\t*\n\t* The required `options.usingOperation` parameter lets you decide if the marker should be managed by operations or not. See\n\t* {@link module:engine/model/markercollection~Marker marker class description} to learn about the difference between\n\t* markers managed by operations and not-managed by operations.\n\t*\n\t* The `options.affectsData` parameter, which defaults to `false`, allows you to define if a marker affects the data. It should be\n\t* `true` when the marker change changes the data returned by the\n\t* {@link module:core/editor/editor~Editor#getData `editor.getData()`} method.\n\t* When set to `true` it fires the {@link module:engine/model/document~ModelDocument#event:change:data `change:data`} event.\n\t* When set to `false` it fires the {@link module:engine/model/document~ModelDocument#event:change `change`} event.\n\t*\n\t* Create marker directly base on marker's name:\n\t*\n\t* ```ts\n\t* addMarker( markerName, { range, usingOperation: false } );\n\t* ```\n\t*\n\t* Create marker using operation:\n\t*\n\t* ```ts\n\t* addMarker( markerName, { range, usingOperation: true } );\n\t* ```\n\t*\n\t* Create marker that affects the editor data:\n\t*\n\t* ```ts\n\t* addMarker( markerName, { range, usingOperation: false, affectsData: true } );\n\t* ```\n\t*\n\t* Note: For efficiency reasons, it's best to create and keep as little markers as possible.\n\t*\n\t* @see module:engine/model/markercollection~Marker\n\t* @param name Name of a marker to create - must be unique.\n\t* @param options.usingOperation Flag indicating that the marker should be added by MarkerOperation.\n\t* See {@link module:engine/model/markercollection~Marker#managedUsingOperations}.\n\t* @param options.range Marker range.\n\t* @param options.affectsData Flag indicating that the marker changes the editor data.\n\t* @returns Marker that was set.\n\t*/\n\taddMarker(name, options) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (!options || typeof options.usingOperation != \"boolean\")\n /**\n\t\t* The `options.usingOperation` parameter is required when adding a new marker.\n\t\t*\n\t\t* @error writer-addmarker-no-usingoperation\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-addmarker-no-usingoperation\", this);\n\t\tconst usingOperation = options.usingOperation;\n\t\tconst range = options.range;\n\t\tconst affectsData = options.affectsData === void 0 ? false : options.affectsData;\n\t\tif (this.model.markers.has(name))\n /**\n\t\t* Marker with provided name already exists.\n\t\t*\n\t\t* @error writer-addmarker-marker-exists\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-addmarker-marker-exists\", this);\n\t\tif (!range)\n /**\n\t\t* Range parameter is required when adding a new marker.\n\t\t*\n\t\t* @error writer-addmarker-no-range\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-addmarker-no-range\", this);\n\t\tif (!usingOperation) return this.model.markers._set(name, range, usingOperation, affectsData);\n\t\tapplyMarkerOperation(this, name, null, range, affectsData);\n\t\treturn this.model.markers.get(name);\n\t}\n\t/**\n\t* Adds, updates or refreshes a {@link module:engine/model/markercollection~Marker marker}. Marker is a named range, which tracks\n\t* changes in the document and updates its range automatically, when model tree changes. Still, it is possible to change the\n\t* marker's range directly using this method.\n\t*\n\t* As the first parameter you can set marker name or instance. If none of them is provided, new marker, with a unique\n\t* name is created and returned.\n\t*\n\t* **Note**: If you want to change the {@link module:engine/view/element~ViewElement view element}\n\t* of the marker while its data in the model\n\t* remains the same, use the dedicated {@link module:engine/controller/editingcontroller~EditingController#reconvertMarker} method.\n\t*\n\t* The `options.usingOperation` parameter lets you change if the marker should be managed by operations or not. See\n\t* {@link module:engine/model/markercollection~Marker marker class description} to learn about the difference between\n\t* markers managed by operations and not-managed by operations. It is possible to change this option for an existing marker.\n\t*\n\t* The `options.affectsData` parameter, which defaults to `false`, allows you to define if a marker affects the data. It should be\n\t* `true` when the marker change changes the data returned by\n\t* the {@link module:core/editor/editor~Editor#getData `editor.getData()`} method.\n\t* When set to `true` it fires the {@link module:engine/model/document~ModelDocument#event:change:data `change:data`} event.\n\t* When set to `false` it fires the {@link module:engine/model/document~ModelDocument#event:change `change`} event.\n\t*\n\t* Update marker directly base on marker's name:\n\t*\n\t* ```ts\n\t* updateMarker( markerName, { range } );\n\t* ```\n\t*\n\t* Update marker using operation:\n\t*\n\t* ```ts\n\t* updateMarker( marker, { range, usingOperation: true } );\n\t* updateMarker( markerName, { range, usingOperation: true } );\n\t* ```\n\t*\n\t* Change marker's option (start using operations to manage it):\n\t*\n\t* ```ts\n\t* updateMarker( marker, { usingOperation: true } );\n\t* ```\n\t*\n\t* Change marker's option (inform the engine, that the marker does not affect the data anymore):\n\t*\n\t* ```ts\n\t* updateMarker( markerName, { affectsData: false } );\n\t* ```\n\t*\n\t* @see module:engine/model/markercollection~Marker\n\t* @param markerOrName Name of a marker to update, or a marker instance.\n\t* @param options If options object is not defined then marker will be refreshed by triggering\n\t* downcast conversion for this marker with the same data.\n\t* @param options.range Marker range to update.\n\t* @param options.usingOperation Flag indicated whether the marker should be added by MarkerOperation.\n\t* See {@link module:engine/model/markercollection~Marker#managedUsingOperations}.\n\t* @param options.affectsData Flag indicating that the marker changes the editor data.\n\t*/\n\tupdateMarker(markerOrName, options) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tconst markerName = typeof markerOrName == \"string\" ? markerOrName : markerOrName.name;\n\t\tconst currentMarker = this.model.markers.get(markerName);\n\t\tif (!currentMarker)\n /**\n\t\t* Marker with provided name does not exist and will not be updated.\n\t\t*\n\t\t* @error writer-updatemarker-marker-not-exists\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-updatemarker-marker-not-exists\", this);\n\t\tif (!options) {\n\t\t\t/**\n\t\t\t* The usage of `writer.updateMarker()` only to reconvert (refresh) a\n\t\t\t* {@link module:engine/model/markercollection~Marker model marker} was deprecated and may not work in the future.\n\t\t\t* Please update your code to use\n\t\t\t* {@link module:engine/controller/editingcontroller~EditingController#reconvertMarker `editor.editing.reconvertMarker()`}\n\t\t\t* instead.\n\t\t\t*\n\t\t\t* @error writer-updatemarker-reconvert-using-editingcontroller\n\t\t\t* @param markerName The name of the updated marker.\n\t\t\t*/\n\t\t\tlogWarning(\"writer-updatemarker-reconvert-using-editingcontroller\", { markerName });\n\t\t\tthis.model.markers._refresh(currentMarker);\n\t\t\treturn;\n\t\t}\n\t\tconst hasUsingOperationDefined = typeof options.usingOperation == \"boolean\";\n\t\tconst affectsDataDefined = typeof options.affectsData == \"boolean\";\n\t\tconst affectsData = affectsDataDefined ? options.affectsData : currentMarker.affectsData;\n\t\tif (!hasUsingOperationDefined && !options.range && !affectsDataDefined)\n /**\n\t\t* One of the options is required - provide range, usingOperations or affectsData.\n\t\t*\n\t\t* @error writer-updatemarker-wrong-options\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-updatemarker-wrong-options\", this);\n\t\tconst currentRange = currentMarker.getRange();\n\t\tconst updatedRange = options.range ? options.range : currentRange;\n\t\tif (hasUsingOperationDefined && options.usingOperation !== currentMarker.managedUsingOperations) {\n\t\t\tif (options.usingOperation) applyMarkerOperation(this, markerName, null, updatedRange, affectsData);\n\t\t\telse {\n\t\t\t\tapplyMarkerOperation(this, markerName, currentRange, null, affectsData);\n\t\t\t\tthis.model.markers._set(markerName, updatedRange, void 0, affectsData);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (currentMarker.managedUsingOperations) applyMarkerOperation(this, markerName, currentRange, updatedRange, affectsData);\n\t\telse this.model.markers._set(markerName, updatedRange, void 0, affectsData);\n\t}\n\t/**\n\t* Removes given {@link module:engine/model/markercollection~Marker marker} or marker with given name.\n\t* The marker is removed accordingly to how it has been created, so if the marker was created using operation,\n\t* it will be destroyed using operation.\n\t*\n\t* @param markerOrName Marker or marker name to remove.\n\t*/\n\tremoveMarker(markerOrName) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tconst name = typeof markerOrName == \"string\" ? markerOrName : markerOrName.name;\n\t\tif (!this.model.markers.has(name))\n /**\n\t\t* Trying to remove marker which does not exist.\n\t\t*\n\t\t* @error writer-removemarker-no-marker\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-removemarker-no-marker\", this);\n\t\tconst marker = this.model.markers.get(name);\n\t\tif (!marker.managedUsingOperations) {\n\t\t\tthis.model.markers._remove(name);\n\t\t\treturn;\n\t\t}\n\t\tconst oldRange = marker.getRange();\n\t\tapplyMarkerOperation(this, name, oldRange, null, marker.affectsData);\n\t}\n\t/**\n\t* Adds a new root to the document (or re-attaches a {@link #detachRoot detached root}).\n\t*\n\t* Throws an error, if trying to add a root that is already added and attached.\n\t*\n\t* **Note:** The default `elementName` value is `'$root'`. When the editor uses a custom root\n\t* {@link module:core/editor/editorconfig~RootConfig#modelElement `modelElement`}, pass the configured model element\n\t* name explicitly so the added root matches the schema the features expect.\n\t* See the {@glink framework/deep-dive/schema#custom-root-elements Custom root elements} section of the\n\t* {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t*\n\t* @param rootName Name of the added root.\n\t* @param elementName The element name. Defaults to `'$root'` which also has some basic schema defined\n\t* (e.g. `$block` elements are allowed inside the `$root`). Make sure to define a proper schema if you use a different name.\n\t* @returns The added root element.\n\t*/\n\taddRoot(rootName, elementName = \"$root\") {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tconst root = this.model.document.getRoot(rootName);\n\t\tif (root && root.isAttached())\n /**\n\t\t* Root with provided name already exists and is attached.\n\t\t*\n\t\t* @error writer-addroot-root-exists\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-addroot-root-exists\", this);\n\t\tconst document = this.model.document;\n\t\tconst operation = new RootOperation(rootName, elementName, true, document, document.version);\n\t\tthis.batch.addOperation(operation);\n\t\tthis.model.applyOperation(operation);\n\t\treturn this.model.document.getRoot(rootName);\n\t}\n\t/**\n\t* Detaches the root from the document.\n\t*\n\t* All content and markers are removed from the root upon detaching. New content and new markers cannot be added to the root, as long\n\t* as it is detached.\n\t*\n\t* A root cannot be fully removed from the document, it can be only detached. A root is permanently removed only after you\n\t* re-initialize the editor and do not specify the root in the initial data.\n\t*\n\t* A detached root can be re-attached using {@link #addRoot}.\n\t*\n\t* Throws an error if the root does not exist or the root is already detached.\n\t*\n\t* @param rootOrName Name of the detached root.\n\t*/\n\tdetachRoot(rootOrName) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tconst root = typeof rootOrName == \"string\" ? this.model.document.getRoot(rootOrName) : rootOrName;\n\t\tif (!root || !root.isAttached())\n /**\n\t\t* Root with provided name does not exist or is already detached.\n\t\t*\n\t\t* @error writer-detachroot-no-root\n\t\t*/\n\t\tthrow new CKEditorError(\"writer-detachroot-no-root\", this);\n\t\tfor (const marker of this.model.markers) if (marker.getRange().root === root) this.removeMarker(marker);\n\t\tfor (const key of root.getAttributeKeys()) this.removeAttribute(key, root);\n\t\tthis.remove(this.createRangeIn(root));\n\t\tconst document = this.model.document;\n\t\tconst operation = new RootOperation(root.rootName, root.name, false, document, document.version);\n\t\tthis.batch.addOperation(operation);\n\t\tthis.model.applyOperation(operation);\n\t}\n\tsetSelection(...args) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tthis.model.document.selection._setTo(...args);\n\t}\n\t/**\n\t* Moves {@link module:engine/model/documentselection~ModelDocumentSelection#focus} to the specified location.\n\t*\n\t* The location can be specified in the same form as\n\t* {@link #createPositionAt `writer.createPositionAt()`} parameters.\n\t*\n\t* @param itemOrPosition\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~ModelItem model item}.\n\t*/\n\tsetSelectionFocus(itemOrPosition, offset) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tthis.model.document.selection._setFocus(itemOrPosition, offset);\n\t}\n\tsetSelectionAttribute(keyOrObjectOrIterable, value) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (typeof keyOrObjectOrIterable === \"string\") this._setSelectionAttribute(keyOrObjectOrIterable, value);\n\t\telse for (const [key, value] of toMap(keyOrObjectOrIterable)) this._setSelectionAttribute(key, value);\n\t}\n\t/**\n\t* Removes attribute(s) with given key(s) from the selection.\n\t*\n\t* Remove one attribute:\n\t*\n\t* ```ts\n\t* writer.removeSelectionAttribute( 'italic' );\n\t* ```\n\t*\n\t* Remove multiple attributes:\n\t*\n\t* ```ts\n\t* writer.removeSelectionAttribute( [ 'italic', 'bold' ] );\n\t* ```\n\t*\n\t* @param keyOrIterableOfKeys Key of the attribute to remove or an iterable of attribute keys to remove.\n\t*/\n\tremoveSelectionAttribute(keyOrIterableOfKeys) {\n\t\tthis._assertWriterUsedCorrectly();\n\t\tif (typeof keyOrIterableOfKeys === \"string\") this._removeSelectionAttribute(keyOrIterableOfKeys);\n\t\telse for (const key of keyOrIterableOfKeys) this._removeSelectionAttribute(key);\n\t}\n\t/**\n\t* Temporarily changes the {@link module:engine/model/documentselection~ModelDocumentSelection#isGravityOverridden gravity}\n\t* of the selection from left to right.\n\t*\n\t* The gravity defines from which direction the selection inherits its attributes. If it's the default left gravity,\n\t* then the selection (after being moved by the user) inherits attributes from its left-hand side.\n\t* This method allows to temporarily override this behavior by forcing the gravity to the right.\n\t*\n\t* For the following model fragment:\n\t*\n\t* ```xml\n\t* <$text bold=\"true\" linkHref=\"url\">bar[]</$text><$text bold=\"true\">biz</$text>\n\t* ```\n\t*\n\t* * Default gravity: selection will have the `bold` and `linkHref` attributes.\n\t* * Overridden gravity: selection will have `bold` attribute.\n\t*\n\t* **Note**: It returns an unique identifier which is required to restore the gravity. It guarantees the symmetry\n\t* of the process.\n\t*\n\t* @returns The unique id which allows restoring the gravity.\n\t*/\n\toverrideSelectionGravity() {\n\t\treturn this.model.document.selection._overrideGravity();\n\t}\n\t/**\n\t* Restores {@link ~ModelWriter#overrideSelectionGravity} gravity to default.\n\t*\n\t* Restoring the gravity is only possible using the unique identifier returned by\n\t* {@link ~ModelWriter#overrideSelectionGravity}. Note that the gravity remains overridden as long as won't be restored\n\t* the same number of times it was overridden.\n\t*\n\t* @param uid The unique id returned by {@link ~ModelWriter#overrideSelectionGravity}.\n\t*/\n\trestoreSelectionGravity(uid) {\n\t\tthis.model.document.selection._restoreGravity(uid);\n\t}\n\t/**\n\t* @param key Key of the attribute to remove.\n\t* @param value Attribute value.\n\t*/\n\t_setSelectionAttribute(key, value) {\n\t\tconst selection = this.model.document.selection;\n\t\tif (selection.isCollapsed && selection.anchor.parent.isEmpty) {\n\t\t\tconst storeKey = ModelDocumentSelection._getStoreAttributeKey(key);\n\t\t\tthis.setAttribute(storeKey, value, selection.anchor.parent);\n\t\t}\n\t\tselection._setAttribute(key, value);\n\t}\n\t/**\n\t* @param key Key of the attribute to remove.\n\t*/\n\t_removeSelectionAttribute(key) {\n\t\tconst selection = this.model.document.selection;\n\t\tif (selection.isCollapsed && selection.anchor.parent.isEmpty) {\n\t\t\tconst storeKey = ModelDocumentSelection._getStoreAttributeKey(key);\n\t\t\tthis.removeAttribute(storeKey, selection.anchor.parent);\n\t\t}\n\t\tselection._removeAttribute(key);\n\t}\n\t/**\n\t* Throws `writer-detached-writer-tries-to-modify-model` error when the writer is used outside of the `change()` block.\n\t*/\n\t_assertWriterUsedCorrectly() {\n\t\t/**\n\t\t* Trying to use a writer outside a {@link module:engine/model/model~Model#change `change()`} or\n\t\t* {@link module:engine/model/model~Model#enqueueChange `enqueueChange()`} blocks.\n\t\t*\n\t\t* The writer can only be used inside these blocks which ensures that the model\n\t\t* can only be changed during such \"sessions\".\n\t\t*\n\t\t* @error writer-incorrect-use\n\t\t*/\n\t\tif (this.model._currentWriter !== this) throw new CKEditorError(\"writer-incorrect-use\", this);\n\t}\n\t/**\n\t* For given action `type` and `positionOrRange` where the action happens, this function finds all affected markers\n\t* and applies a marker operation with the new marker range equal to the current range. Thanks to this, the marker range\n\t* can be later correctly processed during undo.\n\t*\n\t* Exposed so that code applying operations directly to the model can reproduce the same marker bookkeeping.\n\t*\n\t* @internal\n\t* @param type Writer action type.\n\t* @param positionOrRange Position or range where the writer action happens.\n\t*/\n\t_addOperationForAffectedMarkers(type, positionOrRange) {\n\t\tfor (const marker of this.model.markers) {\n\t\t\tif (!marker.managedUsingOperations) continue;\n\t\t\tconst markerRange = marker.getRange();\n\t\t\tlet isAffected;\n\t\t\tif (type === \"move\") {\n\t\t\t\tconst range = positionOrRange;\n\t\t\t\tisAffected = range.containsPosition(markerRange.start) || range.start.isEqual(markerRange.start) || range.containsPosition(markerRange.end) || range.end.isEqual(markerRange.end);\n\t\t\t} else {\n\t\t\t\tconst position = positionOrRange;\n\t\t\t\tconst elementBefore = position.nodeBefore;\n\t\t\t\tconst elementAfter = position.nodeAfter;\n\t\t\t\tconst affectedInLeftElement = markerRange.start.parent == elementBefore && markerRange.start.isAtEnd;\n\t\t\t\tconst affectedInRightElement = markerRange.end.parent == elementAfter && markerRange.end.offset == 0;\n\t\t\t\tconst affectedAfterLeftElement = markerRange.end.nodeAfter == elementAfter;\n\t\t\t\tconst affectedBeforeRightElement = markerRange.start.nodeAfter == elementAfter;\n\t\t\t\tisAffected = affectedInLeftElement || affectedInRightElement || affectedAfterLeftElement || affectedBeforeRightElement;\n\t\t\t}\n\t\t\tif (isAffected) this.updateMarker(marker.name, { range: markerRange });\n\t\t}\n\t}\n};\n/**\n* Sets given attribute to each node in given range. When attribute value is null then attribute will be removed.\n*\n* Because attribute operation needs to have the same attribute value on the whole range, this function splits\n* the range into smaller parts.\n*\n* Given `range` must be flat.\n*/\nfunction setAttributeOnRange(writer, key, value, range) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\tlet lastSplitPosition = range.start;\n\tlet position;\n\tlet valueBefore;\n\tlet valueAfter;\n\tfor (const val of range.getWalker({ shallow: true })) {\n\t\tvalueAfter = val.item.getAttribute(key);\n\t\tif (position && valueBefore != valueAfter) {\n\t\t\tif (valueBefore != value) addOperation();\n\t\t\tlastSplitPosition = position;\n\t\t}\n\t\tposition = val.nextPosition;\n\t\tvalueBefore = valueAfter;\n\t}\n\tif (position instanceof ModelPosition && position != lastSplitPosition && valueBefore != value) addOperation();\n\tfunction addOperation() {\n\t\tconst range = new ModelRange(lastSplitPosition, position);\n\t\tconst version = range.root.document ? doc.version : null;\n\t\tconst operation = new AttributeOperation(range, key, valueBefore, value, version);\n\t\twriter.batch.addOperation(operation);\n\t\tmodel.applyOperation(operation);\n\t}\n}\n/**\n* Sets given attribute to the given node. When attribute value is null then attribute will be removed.\n*/\nfunction setAttributeOnItem(writer, key, value, item) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\tconst previousValue = item.getAttribute(key);\n\tlet range, operation;\n\tif (previousValue != value) {\n\t\tif (item.root === item) {\n\t\t\tconst version = item.document ? doc.version : null;\n\t\t\toperation = new RootAttributeOperation(item, key, previousValue, value, version);\n\t\t} else {\n\t\t\trange = new ModelRange(ModelPosition._createBefore(item), writer.createPositionAfter(item));\n\t\t\tconst version = range.root.document ? doc.version : null;\n\t\t\toperation = new AttributeOperation(range, key, previousValue, value, version);\n\t\t}\n\t\twriter.batch.addOperation(operation);\n\t\tmodel.applyOperation(operation);\n\t}\n}\n/**\n* Creates and applies marker operation to {@link module:engine/model/operation/operation~Operation operation}.\n*/\nfunction applyMarkerOperation(writer, name, oldRange, newRange, affectsData) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\tconst operation = new MarkerOperation(name, oldRange, newRange, model.markers, !!affectsData, doc.version);\n\twriter.batch.addOperation(operation);\n\tmodel.applyOperation(operation);\n}\n/**\n* Creates `MoveOperation` or `DetachOperation` that removes `howMany` nodes starting from `position`.\n* The operation will be applied on given model instance and added to given operation instance.\n*\n* @param position Position from which nodes are removed.\n* @param howMany Number of nodes to remove.\n* @param batch Batch to which the operation will be added.\n* @param model Model instance on which operation will be applied.\n*/\nfunction applyRemoveOperation(position, howMany, batch, model) {\n\tlet operation;\n\tif (position.root.document) {\n\t\tconst doc = model.document;\n\t\tconst graveyardPosition = new ModelPosition(doc.graveyard, [0]);\n\t\toperation = new MoveOperation(position, howMany, graveyardPosition, doc.version);\n\t} else operation = new DetachOperation(position, howMany);\n\tbatch.addOperation(operation);\n\tmodel.applyOperation(operation);\n}\n/**\n* Returns `true` if both root elements are the same element or both are documents root elements.\n*\n* Elements in the same tree can be moved (for instance you can move element form one documents root to another, or\n* within the same document fragment), but when element supposed to be moved from document fragment to the document, or\n* to another document it should be removed and inserted to avoid problems with OT. This is because features like undo or\n* collaboration may track changes on the document but ignore changes on detached fragments and should not get\n* unexpected `move` operation.\n*/\nfunction isSameTree(rootA, rootB) {\n\tif (rootA === rootB) return true;\n\tif (rootA instanceof ModelRootElement && rootB instanceof ModelRootElement) return true;\n\treturn false;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/utils/selection-post-fixer\n*/\n/**\n* Injects selection post-fixer to the model.\n*\n* The role of the selection post-fixer is to ensure that the selection is in a correct place\n* after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n*\n* The correct position means that:\n*\n* * All collapsed selection ranges are in a place where the {@link module:engine/model/schema~ModelSchema}\n* allows a `$text`.\n* * None of the selection's non-collapsed ranges crosses a {@link module:engine/model/schema~ModelSchema#isLimit limit element}\n* boundary (a range must be rooted within one limit element).\n* * Only {@link module:engine/model/schema~ModelSchema#isSelectable selectable elements} can be selected from the outside\n* (e.g. `[<paragraph>foo</paragraph>]` is invalid). This rule applies independently to both selection ends, so this\n* selection is correct: `<paragraph>f[oo</paragraph><imageBlock></imageBlock>]`.\n*\n* If the position is not correct, the post-fixer will automatically correct it.\n*\n* ## Fixing a non-collapsed selection\n*\n* See as an example a selection that starts in a P1 element and ends inside the text of a TD element\n* (`[` and `]` are range boundaries and `(l)` denotes an element defined as `isLimit=true`):\n*\n* ```\n* root\n* |- element P1\n* | |- \"foo\" root\n* |- element TABLE (l) P1 TABLE P2\n* | |- element TR (l) f o[o TR TR b a r\n* | | |- element TD (l) TD TD\n* | | |- \"aaa\" a]a a b b b\n* | |- element TR (l)\n* | | |- element TD (l) ||\n* | | |- \"bbb\" ||\n* |- element P2 VV\n* | |- \"bar\"\n* root\n* P1 TABLE] P2\n* f o[o TR TR b a r\n* TD TD\n* a a a b b b\n* ```\n*\n* In the example above, the TABLE, TR and TD are defined as `isLimit=true` in the schema. The range which is not contained within\n* a single limit element must be expanded to select the outermost limit element. The range end is inside the text node of the TD element.\n* As the TD element is a child of the TR and TABLE elements, where both are defined as `isLimit=true` in the schema, the range must be\n* expanded to select the whole TABLE element.\n*\n* **Note** If the selection contains multiple ranges, the method returns a minimal set of ranges that are not intersecting after expanding\n* them to select `isLimit=true` elements.\n*\n* @internal\n*/\nfunction injectSelectionPostFixer(model) {\n\tmodel.document.registerPostFixer((writer) => selectionPostFixer(writer, model));\n}\n/**\n* The selection post-fixer.\n*/\nfunction selectionPostFixer(writer, model) {\n\tconst selection = model.document.selection;\n\tconst schema = model.schema;\n\tconst ranges = [];\n\tlet wasFixed = false;\n\tfor (const modelRange of selection.getRanges()) {\n\t\tconst correctedRange = tryFixingRange(modelRange, schema);\n\t\tif (correctedRange && !correctedRange.isEqual(modelRange)) {\n\t\t\tranges.push(correctedRange);\n\t\t\twasFixed = true;\n\t\t} else ranges.push(modelRange);\n\t}\n\tif (wasFixed) writer.setSelection(mergeIntersectingRanges(ranges), { backward: selection.isBackward });\n\treturn false;\n}\n/**\n* Tries fixing a range if it's incorrect.\n*\n* **Note:** This helper is used by the selection post-fixer and to fix the `beforeinput` target ranges.\n*\n* @returns Returns fixed range or null if range is valid.\n* @internal\n*/\nfunction tryFixingRange(range, schema) {\n\tif (range.isCollapsed) return tryFixingCollapsedRange(range, schema);\n\treturn tryFixingNonCollapsedRage(range, schema);\n}\n/**\n* Tries to fix collapsed ranges.\n*\n* * Fixes situation when a range is in a place where $text is not allowed\n*\n* @param range Collapsed range to fix.\n* @returns Returns fixed range or null if range is valid.\n*/\nfunction tryFixingCollapsedRange(range, schema) {\n\tconst originalPosition = range.start;\n\tconst nearestSelectionRange = schema.getNearestSelectionRange(originalPosition);\n\tif (!nearestSelectionRange) {\n\t\tconst ancestorObject = originalPosition.getAncestors().reverse().find((item) => schema.isObject(item));\n\t\tif (ancestorObject) return ModelRange._createOn(ancestorObject);\n\t\treturn null;\n\t}\n\tif (!nearestSelectionRange.isCollapsed) return nearestSelectionRange;\n\tconst fixedPosition = nearestSelectionRange.start;\n\tif (originalPosition.isEqual(fixedPosition)) return null;\n\treturn new ModelRange(fixedPosition);\n}\n/**\n* Tries to fix an expanded range.\n*\n* @param range Expanded range to fix.\n* @returns Returns fixed range or null if range is valid.\n*/\nfunction tryFixingNonCollapsedRage(range, schema) {\n\tconst { start, end } = range;\n\tconst isTextAllowedOnStart = schema.checkChild(start, \"$text\");\n\tconst isTextAllowedOnEnd = schema.checkChild(end, \"$text\");\n\tconst startLimitElement = schema.getLimitElement(start);\n\tconst endLimitElement = schema.getLimitElement(end);\n\tif (startLimitElement === endLimitElement) {\n\t\tif (isTextAllowedOnStart && isTextAllowedOnEnd) return null;\n\t\tif (checkSelectionOnNonLimitElements(start, end, schema)) {\n\t\t\tconst fixedStart = start.nodeAfter && schema.isSelectable(start.nodeAfter) ? null : schema.getNearestSelectionRange(start, \"forward\");\n\t\t\tconst fixedEnd = end.nodeBefore && schema.isSelectable(end.nodeBefore) ? null : schema.getNearestSelectionRange(end, \"backward\");\n\t\t\tconst rangeStart = fixedStart ? fixedStart.start : start;\n\t\t\tconst rangeEnd = fixedEnd ? fixedEnd.end : end;\n\t\t\treturn new ModelRange(rangeStart, rangeEnd);\n\t\t}\n\t}\n\tconst isStartInLimit = startLimitElement && !startLimitElement.is(\"rootElement\");\n\tconst isEndInLimit = endLimitElement && !endLimitElement.is(\"rootElement\");\n\tif (isStartInLimit || isEndInLimit) {\n\t\tconst bothInSameParent = start.nodeAfter && end.nodeBefore && start.nodeAfter.parent === end.nodeBefore.parent;\n\t\tconst expandStart = isStartInLimit && (!bothInSameParent || !isSelectable(start.nodeAfter, schema));\n\t\tconst expandEnd = isEndInLimit && (!bothInSameParent || !isSelectable(end.nodeBefore, schema));\n\t\tlet fixedStart = start;\n\t\tlet fixedEnd = end;\n\t\tif (expandStart) fixedStart = ModelPosition._createBefore(findOutermostLimitAncestor(startLimitElement, schema));\n\t\tif (expandEnd) fixedEnd = ModelPosition._createAfter(findOutermostLimitAncestor(endLimitElement, schema));\n\t\treturn new ModelRange(fixedStart, fixedEnd);\n\t}\n\treturn null;\n}\n/**\n* Finds the outer-most ancestor.\n*/\nfunction findOutermostLimitAncestor(startingNode, schema) {\n\tlet isLimitNode = startingNode;\n\tlet parent = isLimitNode;\n\twhile (schema.isLimit(parent) && parent.parent) {\n\t\tisLimitNode = parent;\n\t\tparent = parent.parent;\n\t}\n\treturn isLimitNode;\n}\n/**\n* Checks whether any of range boundaries is placed around non-limit elements.\n*/\nfunction checkSelectionOnNonLimitElements(start, end, schema) {\n\tconst startIsOnBlock = start.nodeAfter && !schema.isLimit(start.nodeAfter) || schema.checkChild(start, \"$text\");\n\tconst endIsOnBlock = end.nodeBefore && !schema.isLimit(end.nodeBefore) || schema.checkChild(end, \"$text\");\n\treturn startIsOnBlock || endIsOnBlock;\n}\n/**\n* Returns a minimal non-intersecting array of ranges without duplicates.\n*\n* @param ranges Ranges to merge.\n* @returns Array of unique and non-intersecting ranges.\n* @internal\n*/\nfunction mergeIntersectingRanges(ranges) {\n\tconst rangesToMerge = [...ranges];\n\tconst rangeIndexesToRemove = /* @__PURE__ */ new Set();\n\tlet currentRangeIndex = 1;\n\twhile (currentRangeIndex < rangesToMerge.length) {\n\t\tconst currentRange = rangesToMerge[currentRangeIndex];\n\t\tconst previousRanges = rangesToMerge.slice(0, currentRangeIndex);\n\t\tfor (const [previousRangeIndex, previousRange] of previousRanges.entries()) {\n\t\t\tif (rangeIndexesToRemove.has(previousRangeIndex)) continue;\n\t\t\tif (currentRange.isEqual(previousRange)) rangeIndexesToRemove.add(previousRangeIndex);\n\t\t\telse if (currentRange.isIntersecting(previousRange)) {\n\t\t\t\trangeIndexesToRemove.add(previousRangeIndex);\n\t\t\t\trangeIndexesToRemove.add(currentRangeIndex);\n\t\t\t\tconst mergedRange = currentRange.getJoined(previousRange);\n\t\t\t\trangesToMerge.push(mergedRange);\n\t\t\t}\n\t\t}\n\t\tcurrentRangeIndex++;\n\t}\n\treturn rangesToMerge.filter((_, index) => !rangeIndexesToRemove.has(index));\n}\n/**\n* Checks if node exists and if it's a selectable.\n*/\nfunction isSelectable(node, schema) {\n\treturn node && schema.isSelectable(node);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/utils/deletecontent\n*/\n/**\n* Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n*\n* **Note:** Use {@link module:engine/model/model~Model#deleteContent} instead of this function.\n* This function is only exposed to be reusable in algorithms\n* which change the {@link module:engine/model/model~Model#deleteContent}\n* method's behavior.\n*\n* @param model The model in context of which the insertion should be performed.\n* @param selection Selection of which the content should be deleted.\n* @param options.leaveUnmerged Whether to merge elements after removing the content of the selection.\n*\n* For example `<heading>x[x</heading><paragraph>y]y</paragraph>` will become:\n*\n* * `<heading>x^y</heading>` with the option disabled (`leaveUnmerged == false`)\n* * `<heading>x^</heading><paragraph>y</paragraph>` with enabled (`leaveUnmerged == true`).\n*\n* Note: {@link module:engine/model/schema~ModelSchema#isObject object} and {@link module:engine/model/schema~ModelSchema#isLimit limit}\n* elements will not be merged.\n*\n* @param options.doNotResetEntireContent Whether to skip replacing the entire content with a\n* paragraph when the entire content was selected.\n*\n* For example `<heading>[x</heading><paragraph>y]</paragraph>` will become:\n*\n* * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)\n* * `<heading>^</heading>` with enabled (`doNotResetEntireContent == true`).\n*\n* @param options.doNotAutoparagraph Whether to create a paragraph if after content deletion selection is moved\n* to a place where text cannot be inserted.\n*\n* For example `<paragraph>x</paragraph>[<imageBlock src=\"foo.jpg\"></imageBlock>]` will become:\n*\n* * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`)\n* * `<paragraph>x</paragraph>[]` with the option enabled (`doNotAutoparagraph == true`).\n*\n* If you use this option you need to make sure to handle invalid selections yourself or leave\n* them to the selection post-fixer (may not always work).\n*\n* **Note:** If there is no valid position for the selection, the paragraph will always be created:\n*\n* `[<imageBlock src=\"foo.jpg\"></imageBlock>]` -> `<paragraph>[]</paragraph>`.\n*\n* @param options.doNotFixSelection Whether given selection-to-remove should be fixed if it ends at the beginning of an element.\n*\n* By default, `deleteContent()` will fix selection before performing a deletion, so that the selection does not end at the beginning of\n* an element. For example, selection `<heading>[Heading</heading><paragraph>]Some text.</paragraph>` will be treated as it was\n* `<heading>[Heading]</heading><paragraph>Some text.</paragraph>`. As a result, the elements will not get merged.\n*\n* If selection is as in example, visually, the next element (paragraph) is not selected and it may be confusing for the user that\n* the elements got merged. Selection is set up like this by browsers when a user triple-clicks on some text.\n*\n* However, in some cases, it is expected to remove content exactly as selected in the selection, without any fixing. In these cases,\n* this flag can be set to `true`, which will prevent fixing the selection.\n*\n* @internal\n*/\nfunction deleteContent(model, selection, options = {}) {\n\tif (selection.isCollapsed) return;\n\tconst selRange = selection.getFirstRange();\n\tif (selRange.root.rootName == \"$graveyard\") return;\n\tconst schema = model.schema;\n\tconst documentSelection = model.document.selection;\n\tconst selectionIsDocumentSelection = isRelatedToDocumentSelection(selection, documentSelection, selRange);\n\tconst selectionAttributes = Array.from(documentSelection.getAttributes());\n\tconst selectionParentWasEmpty = !!documentSelection.getFirstRange()?.start.parent.isEmpty;\n\tmodel.change((writer) => {\n\t\tif (!options.doNotResetEntireContent && shouldEntireContentBeReplacedWithParagraph(schema, selection)) {\n\t\t\treplaceEntireContentWithParagraph(writer, selection);\n\t\t\treturn;\n\t\t}\n\t\tconst attributesForAutoparagraph = {};\n\t\tif (!options.doNotAutoparagraph) {\n\t\t\tconst selectedElement = selection.getSelectedElement();\n\t\t\tif (selectedElement) Object.assign(attributesForAutoparagraph, schema.getAttributesWithProperty(selectedElement, \"copyOnReplace\", true));\n\t\t}\n\t\tlet startPosition, endPosition;\n\t\tif (selRange.root instanceof ModelDocumentFragment) {\n\t\t\tstartPosition = ModelLivePosition._fromPositionInDocumentFragment(selRange.start, model, \"toPrevious\");\n\t\t\tendPosition = ModelLivePosition._fromPositionInDocumentFragment(selRange.end, model, \"toNext\");\n\t\t} else if (!options.doNotFixSelection) [startPosition, endPosition] = getLivePositionsForSelectedBlocks(selRange);\n\t\telse {\n\t\t\tstartPosition = ModelLivePosition.fromPosition(selRange.start, \"toPrevious\");\n\t\t\tendPosition = ModelLivePosition.fromPosition(selRange.end, \"toNext\");\n\t\t}\n\t\tif (!startPosition.isTouching(endPosition)) writer.remove(writer.createRange(startPosition, endPosition));\n\t\tif (!options.leaveUnmerged) {\n\t\t\tmergeBranches(writer, startPosition, endPosition);\n\t\t\tschema.removeDisallowedAttributes(startPosition.parent.getChildren(), writer);\n\t\t}\n\t\tcollapseSelectionAt(writer, selection, startPosition);\n\t\tif (!options.doNotAutoparagraph && shouldAutoparagraph(schema, startPosition)) insertParagraph(writer, startPosition, selection, attributesForAutoparagraph);\n\t\tif (selectionIsDocumentSelection) restoreSelectionAttributesOnEmptyParent(writer, selectionAttributes, selectionParentWasEmpty);\n\t\tstartPosition.detach();\n\t\tendPosition.detach();\n\t});\n}\n/**\n* Returns the live positions for the range adjusted to span only blocks selected from the user perspective. Example:\n*\n* ```\n* <heading1>[foo</heading1>\n* <paragraph>bar</paragraph>\n* <heading1>]abc</heading1> <-- this block is not considered as selected\n* ```\n*\n* This is the same behavior as in Selection#getSelectedBlocks() \"special case\".\n*/\nfunction getLivePositionsForSelectedBlocks(range) {\n\tconst model = range.root.document.model;\n\tconst startPosition = range.start;\n\tlet endPosition = range.end;\n\tif (model.hasContent(range, { ignoreMarkers: true })) {\n\t\tconst endBlock = getParentBlock(endPosition);\n\t\tif (endBlock && endPosition.isTouching(model.createPositionAt(endBlock, 0))) {\n\t\t\tconst selection = model.createSelection(range);\n\t\t\tmodel.modifySelection(selection, { direction: \"backward\" });\n\t\t\tconst newEndPosition = selection.getLastPosition();\n\t\t\tconst skippedRange = model.createRange(newEndPosition, endPosition);\n\t\t\tif (!model.hasContent(skippedRange, { ignoreMarkers: true })) endPosition = newEndPosition;\n\t\t}\n\t}\n\treturn [ModelLivePosition.fromPosition(startPosition, \"toPrevious\"), ModelLivePosition.fromPosition(endPosition, \"toNext\")];\n}\n/**\n* Finds the lowest element in position's ancestors which is a block.\n* Returns null if a limit element is encountered before reaching a block element.\n*/\nfunction getParentBlock(position) {\n\tconst element = position.parent;\n\tconst schema = element.root.document.model.schema;\n\tconst ancestors = element.getAncestors({\n\t\tparentFirst: true,\n\t\tincludeSelf: true\n\t});\n\tfor (const element of ancestors) {\n\t\tif (schema.isLimit(element)) return null;\n\t\tif (schema.isBlock(element)) return element;\n\t}\n}\n/**\n* This function is a result of reaching the Ballmer's peak for just the right amount of time.\n* Even I had troubles documenting it after a while and after reading it again I couldn't believe that it really works.\n*/\nfunction mergeBranches(writer, startPosition, endPosition) {\n\tconst model = writer.model;\n\tif (!checkShouldMerge(writer.model.schema, startPosition, endPosition)) return;\n\tconst [startAncestor, endAncestor] = getAncestorsJustBelowCommonAncestor(startPosition, endPosition);\n\tif (!startAncestor || !endAncestor) return;\n\tif (!model.hasContent(startAncestor, { ignoreMarkers: true }) && model.hasContent(endAncestor, { ignoreMarkers: true })) mergeBranchesRight(writer, startPosition, endPosition, startAncestor.parent);\n\telse mergeBranchesLeft(writer, startPosition, endPosition, startAncestor.parent);\n}\n/**\n* Merging blocks to the left (properties of the left block are preserved).\n* Simple example:\n*\n* ```\n* <heading1>foo[</heading1> -> <heading1>foo[bar</heading1>]\n* <paragraph>]bar</paragraph> -> --^\n* ```\n*\n* Nested example:\n*\n* ```\n* <blockQuote> -> <blockQuote>\n* <heading1>foo[</heading1> -> <heading1>foo[bar</heading1>\n* </blockQuote> -> </blockQuote>] ^\n* <blockBlock> -> |\n* <paragraph>]bar</paragraph> -> ---\n* </blockBlock> ->\n* ```\n*/\nfunction mergeBranchesLeft(writer, startPosition, endPosition, commonAncestor) {\n\tconst startElement = startPosition.parent;\n\tconst endElement = endPosition.parent;\n\tif (startElement == commonAncestor || endElement == commonAncestor) return;\n\tstartPosition = writer.createPositionAfter(startElement);\n\tendPosition = writer.createPositionBefore(endElement);\n\tif (!endPosition.isEqual(startPosition)) writer.insert(endElement, startPosition);\n\twriter.merge(startPosition);\n\twhile (endPosition.parent.isEmpty) {\n\t\tconst parentToRemove = endPosition.parent;\n\t\tendPosition = writer.createPositionBefore(parentToRemove);\n\t\twriter.remove(parentToRemove);\n\t}\n\tif (!checkShouldMerge(writer.model.schema, startPosition, endPosition)) return;\n\tmergeBranchesLeft(writer, startPosition, endPosition, commonAncestor);\n}\n/**\n* Merging blocks to the right (properties of the right block are preserved).\n* Simple example:\n*\n* ```\n* <heading1>foo[</heading1> -> --v\n* <paragraph>]bar</paragraph> -> [<paragraph>foo]bar</paragraph>\n* ```\n*\n* Nested example:\n*\n* ```\n* <blockQuote> ->\n* <heading1>foo[</heading1> -> ---\n* </blockQuote> -> |\n* <blockBlock> -> [<blockBlock> v\n* <paragraph>]bar</paragraph> -> <paragraph>foo]bar</paragraph>\n* </blockBlock> -> </blockBlock>\n* ```\n*/\nfunction mergeBranchesRight(writer, startPosition, endPosition, commonAncestor) {\n\tconst startElement = startPosition.parent;\n\tconst endElement = endPosition.parent;\n\tif (startElement == commonAncestor || endElement == commonAncestor) return;\n\tstartPosition = writer.createPositionAfter(startElement);\n\tendPosition = writer.createPositionBefore(endElement);\n\tif (!endPosition.isEqual(startPosition)) writer.insert(startElement, endPosition);\n\twhile (startPosition.parent.isEmpty) {\n\t\tconst parentToRemove = startPosition.parent;\n\t\tstartPosition = writer.createPositionBefore(parentToRemove);\n\t\twriter.remove(parentToRemove);\n\t}\n\tendPosition = writer.createPositionBefore(endElement);\n\tmergeRight(writer, endPosition);\n\tif (!checkShouldMerge(writer.model.schema, startPosition, endPosition)) return;\n\tmergeBranchesRight(writer, startPosition, endPosition, commonAncestor);\n}\n/**\n* There is no right merge operation so we need to simulate it.\n*/\nfunction mergeRight(writer, position) {\n\tconst startElement = position.nodeBefore;\n\tconst endElement = position.nodeAfter;\n\tif (startElement.name != endElement.name) writer.rename(startElement, endElement.name);\n\twriter.clearAttributes(startElement);\n\twriter.setAttributes(Object.fromEntries(endElement.getAttributes()), startElement);\n\twriter.merge(position);\n}\n/**\n* Verifies if merging is needed and possible. It's not needed if both positions are in the same element\n* and it's not possible if some element is a limit or the range crosses a limit element.\n*/\nfunction checkShouldMerge(schema, startPosition, endPosition) {\n\tconst startElement = startPosition.parent;\n\tconst endElement = endPosition.parent;\n\tif (startElement == endElement) return false;\n\tif (schema.isLimit(startElement) || schema.isLimit(endElement)) return false;\n\treturn isCrossingLimitElement(startPosition, endPosition, schema);\n}\n/**\n* Returns the elements that are the ancestors of the provided positions that are direct children of the common ancestor.\n*/\nfunction getAncestorsJustBelowCommonAncestor(positionA, positionB) {\n\tconst ancestorsA = positionA.getAncestors();\n\tconst ancestorsB = positionB.getAncestors();\n\tlet i = 0;\n\twhile (ancestorsA[i] && ancestorsA[i] == ancestorsB[i]) i++;\n\treturn [ancestorsA[i], ancestorsB[i]];\n}\nfunction shouldAutoparagraph(schema, position) {\n\tconst isTextAllowed = schema.checkChild(position, \"$text\");\n\tconst isParagraphAllowed = schema.checkChild(position, \"paragraph\");\n\treturn !isTextAllowed && isParagraphAllowed;\n}\n/**\n* Check if parents of two positions can be merged by checking if there are no limit/object\n* boundaries between those two positions.\n*\n* E.g. in <bQ><p>x[]</p></bQ><widget><caption>{}</caption></widget>\n* we'll check <p>, <bQ>, <widget> and <caption>.\n* Usually, widget and caption are marked as objects/limits in the schema, so in this case merging will be blocked.\n*/\nfunction isCrossingLimitElement(leftPos, rightPos, schema) {\n\tconst rangeToCheck = new ModelRange(leftPos, rightPos);\n\tfor (const value of rangeToCheck.getWalker()) if (schema.isLimit(value.item)) return false;\n\treturn true;\n}\nfunction insertParagraph(writer, position, selection, attributes = {}) {\n\tconst paragraph = writer.createElement(\"paragraph\");\n\twriter.model.schema.setAllowedAttributes(paragraph, attributes, writer);\n\twriter.insert(paragraph, position);\n\tcollapseSelectionAt(writer, selection, writer.createPositionAt(paragraph, 0));\n}\nfunction replaceEntireContentWithParagraph(writer, selection) {\n\tconst limitElement = writer.model.schema.getLimitElement(selection);\n\twriter.remove(writer.createRangeIn(limitElement));\n\tinsertParagraph(writer, writer.createPositionAt(limitElement, 0), selection);\n}\n/**\n* We want to replace the entire content with a paragraph when:\n* * the entire content is selected,\n* * selection contains at least two elements,\n* * whether the paragraph is allowed in schema in the common ancestor.\n*/\nfunction shouldEntireContentBeReplacedWithParagraph(schema, selection) {\n\tconst limitElement = schema.getLimitElement(selection);\n\tif (!selection.containsEntireContent(limitElement)) return false;\n\tconst range = selection.getFirstRange();\n\tif (range.start.parent == range.end.parent) return false;\n\treturn schema.checkChild(limitElement, \"paragraph\");\n}\n/**\n* Helper function that sets the selection. Depending whether given `selection` is a document selection or not,\n* uses a different method to set it.\n*/\nfunction collapseSelectionAt(writer, selection, positionOrRange) {\n\tif (selection instanceof ModelDocumentSelection) writer.setSelection(positionOrRange);\n\telse selection.setTo(positionOrRange);\n}\n/**\n* Restores the document selection attributes after a deletion that leaves the selection in an empty parent block.\n* This preserves the pre-delete formatting (e.g. bold, italic) so that subsequent typing continues in the same style.\n*\n* Attributes are only restored when:\n* - There were attributes on the selection before the deletion.\n* - The deletion left the document selection's parent block empty.\n* - The parent block was **not** already empty before the deletion — this ensures that attributes are not\n* re-applied when `deleteContent()` was called on a completely unrelated block.\n*/\nfunction restoreSelectionAttributesOnEmptyParent(writer, selectionAttributes, selectionParentWasEmpty) {\n\tif (!selectionAttributes.length) return;\n\tconst documentSelection = writer.model.document.selection;\n\tif (!documentSelection.anchor.parent.isEmpty) return;\n\tif (selectionParentWasEmpty) return;\n\tfor (const [key, value] of selectionAttributes) if (writer.model.schema.getAttributeProperties(key).isFormatting && writer.model.schema.checkAttributeInSelection(documentSelection, key)) writer.setSelectionAttribute(key, value);\n}\n/**\n* Checks whether the provided selection is related to the document selection.\n*\n* Returns `true` when:\n* - the selection is a `DocumentSelection` instance, or\n* - the document selection is collapsed and sits at the start or end of the given range, or\n* - the document selection is not collapsed and its range intersects the given range.\n*/\nfunction isRelatedToDocumentSelection(selection, documentSelection, selRange) {\n\tif (selection instanceof ModelDocumentSelection) return true;\n\tif (documentSelection.isCollapsed) {\n\t\tconst position = documentSelection.getFirstPosition();\n\t\treturn position.isEqual(selRange.start) || position.isEqual(selRange.end);\n\t}\n\treturn !!documentSelection.getFirstRange()?.isIntersecting(selRange);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Gets a clone of the selected content.\n*\n* For example, for the following selection:\n*\n* ```html\n* <p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n* ```\n*\n* It will return a document fragment with such a content:\n*\n* ```html\n* <quote><h>st</h></quote><p>se</p>\n* ```\n*\n* @param model The model in context of which the selection modification should be performed.\n* @param selection The selection of which content will be returned.\n* @internal\n*/\nfunction getSelectedContent(model, selection) {\n\treturn model.change((writer) => {\n\t\tconst frag = writer.createDocumentFragment();\n\t\tconst range = selection.getFirstRange();\n\t\tif (!range || range.isCollapsed) return frag;\n\t\tconst root = range.start.root;\n\t\tconst commonPath = range.start.getCommonPath(range.end);\n\t\tconst commonParent = root.getNodeByPath(commonPath);\n\t\tlet flatSubtreeRange;\n\t\tif (range.start.parent == range.end.parent) flatSubtreeRange = range;\n\t\telse flatSubtreeRange = writer.createRange(writer.createPositionAt(commonParent, range.start.path[commonPath.length]), writer.createPositionAt(commonParent, range.end.path[commonPath.length] + 1));\n\t\tconst howMany = flatSubtreeRange.end.offset - flatSubtreeRange.start.offset;\n\t\tfor (const item of flatSubtreeRange.getItems({ shallow: true })) if (item.is(\"$textProxy\")) writer.appendText(item.data, item.getAttributes(), frag);\n\t\telse writer.append(writer.cloneElement(item, true), frag);\n\t\tif (flatSubtreeRange != range) {\n\t\t\tconst newRange = range._getTransformedByMove(flatSubtreeRange.start, writer.createPositionAt(frag, 0), howMany)[0];\n\t\t\tconst leftExcessRange = writer.createRange(writer.createPositionAt(frag, 0), newRange.start);\n\t\t\tremoveRangeContent(writer.createRange(newRange.end, writer.createPositionAt(frag, \"end\")), writer);\n\t\t\tremoveRangeContent(leftExcessRange, writer);\n\t\t}\n\t\treturn frag;\n\t});\n}\nfunction removeRangeContent(range, writer) {\n\tconst parentsToCheck = [];\n\tArray.from(range.getItems({ direction: \"backward\" })).map((item) => writer.createRangeOn(item)).filter((itemRange) => {\n\t\treturn (itemRange.start.isAfter(range.start) || itemRange.start.isEqual(range.start)) && (itemRange.end.isBefore(range.end) || itemRange.end.isEqual(range.end));\n\t}).forEach((itemRange) => {\n\t\tparentsToCheck.push(itemRange.start.parent);\n\t\twriter.remove(itemRange);\n\t});\n\tparentsToCheck.forEach((parentToCheck) => {\n\t\tlet parent = parentToCheck;\n\t\twhile (parent.parent && parent.isEmpty) {\n\t\t\tconst removeRange = writer.createRangeOn(parent);\n\t\t\tparent = parent.parent;\n\t\t\twriter.remove(removeRange);\n\t\t}\n\t});\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/utils/insertcontent\n*/\n/**\n* Inserts content into the editor (specified selection) as one would expect the paste functionality to work.\n*\n* It takes care of removing the selected content, splitting elements (if needed), inserting elements and merging elements appropriately.\n*\n* Some examples:\n*\n* ```html\n* <p>x^</p> + <p>y</p> => <p>x</p><p>y</p> => <p>xy[]</p>\n* <p>x^y</p> + <p>z</p> => <p>x</p>^<p>y</p> + <p>z</p> => <p>x</p><p>z</p><p>y</p> => <p>xz[]y</p>\n* <p>x^y</p> + <img /> => <p>x</p>^<p>y</p> + <img /> => <p>x</p><img /><p>y</p>\n* <p>x</p><p>^</p><p>z</p> + <p>y</p> => <p>x</p><p>y[]</p><p>z</p> (no merging)\n* <p>x</p>[<img />]<p>z</p> + <p>y</p> => <p>x</p>^<p>z</p> + <p>y</p> => <p>x</p><p>y[]</p><p>z</p>\n* ```\n*\n* If an instance of {@link module:engine/model/selection~ModelSelection} is passed as `selectable` it will be modified\n* to the insertion selection (equal to a range to be selected after insertion).\n*\n* If `selectable` is not passed, the content will be inserted using the current selection of the model document.\n*\n* **Note:** Use {@link module:engine/model/model~Model#insertContent} instead of this function.\n* This function is only exposed to be reusable in algorithms which change the {@link module:engine/model/model~Model#insertContent}\n* method's behavior.\n*\n* @param model The model in context of which the insertion should be performed.\n* @param content The content to insert.\n* @param selectable Selection into which the content should be inserted.\n* @returns Range which contains all the performed changes. This is a range that, if removed,\n* would return the model to the state before the insertion. If no changes were preformed by `insertContent`, returns a range collapsed\n* at the insertion position.\n* @internal\n*/\nfunction insertContent(model, content, selectable) {\n\treturn model.change((writer) => {\n\t\tconst selection = selectable ? selectable : model.document.selection;\n\t\tif (!selection.isCollapsed) model.deleteContent(selection, { doNotAutoparagraph: true });\n\t\tconst insertion = new Insertion(model, writer, selection.anchor);\n\t\tconst fakeMarkerElements = [];\n\t\tlet nodesToInsert;\n\t\tif (content.is(\"documentFragment\")) {\n\t\t\tif (content.markers.size) {\n\t\t\t\tconst markersPosition = [];\n\t\t\t\tfor (const [name, range] of content.markers) {\n\t\t\t\t\tconst { start, end } = range;\n\t\t\t\t\tconst isCollapsed = start.isEqual(end);\n\t\t\t\t\tmarkersPosition.push({\n\t\t\t\t\t\tposition: start,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tisCollapsed\n\t\t\t\t\t}, {\n\t\t\t\t\t\tposition: end,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tisCollapsed\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tmarkersPosition.sort(({ position: posA }, { position: posB }) => posA.isBefore(posB) ? 1 : -1);\n\t\t\t\tfor (const { position, name, isCollapsed } of markersPosition) {\n\t\t\t\t\tlet fakeElement = null;\n\t\t\t\t\tlet collapsed = null;\n\t\t\t\t\tconst isAtBeginning = position.parent === content && position.isAtStart;\n\t\t\t\t\tconst isAtEnd = position.parent === content && position.isAtEnd;\n\t\t\t\t\tif (!isAtBeginning && !isAtEnd) {\n\t\t\t\t\t\tfakeElement = writer.createElement(\"$marker\");\n\t\t\t\t\t\twriter.insert(fakeElement, position);\n\t\t\t\t\t} else if (isCollapsed) collapsed = isAtBeginning ? \"start\" : \"end\";\n\t\t\t\t\tfakeMarkerElements.push({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\telement: fakeElement,\n\t\t\t\t\t\tcollapsed\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tnodesToInsert = content.getChildren();\n\t\t} else nodesToInsert = [content];\n\t\tinsertion.handleNodes(nodesToInsert);\n\t\tlet newRange = insertion.getSelectionRange();\n\t\tif (content.is(\"documentFragment\") && fakeMarkerElements.length) {\n\t\t\tconst selectionLiveRange = newRange ? ModelLiveRange.fromRange(newRange) : null;\n\t\t\tconst markersData = {};\n\t\t\tfor (let i = fakeMarkerElements.length - 1; i >= 0; i--) {\n\t\t\t\tconst { name, element, collapsed } = fakeMarkerElements[i];\n\t\t\t\tconst isStartBoundary = !markersData[name];\n\t\t\t\tif (isStartBoundary) markersData[name] = [];\n\t\t\t\tif (element) {\n\t\t\t\t\tconst elementPosition = writer.createPositionAt(element, \"before\");\n\t\t\t\t\tmarkersData[name].push(elementPosition);\n\t\t\t\t\twriter.remove(element);\n\t\t\t\t} else {\n\t\t\t\t\tconst rangeOnInsertion = insertion.getAffectedRange();\n\t\t\t\t\tif (!rangeOnInsertion) {\n\t\t\t\t\t\tif (collapsed) markersData[name].push(insertion.position);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (collapsed) markersData[name].push(rangeOnInsertion[collapsed]);\n\t\t\t\t\telse markersData[name].push(isStartBoundary ? rangeOnInsertion.start : rangeOnInsertion.end);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [name, [start, end]] of Object.entries(markersData)) if (start && end && start.root === end.root && start.root.document && !writer.model.markers.has(name)) writer.addMarker(name, {\n\t\t\t\tusingOperation: true,\n\t\t\t\taffectsData: true,\n\t\t\t\trange: new ModelRange(start, end)\n\t\t\t});\n\t\t\tif (selectionLiveRange) {\n\t\t\t\tnewRange = selectionLiveRange.toRange();\n\t\t\t\tselectionLiveRange.detach();\n\t\t\t}\n\t\t}\n\t\tif (newRange) if (selection instanceof ModelDocumentSelection) writer.setSelection(newRange);\n\t\telse selection.setTo(newRange);\n\t\tconst affectedRange = insertion.getAffectedRange() || model.createRange(selection.anchor);\n\t\tinsertion.destroy();\n\t\treturn affectedRange;\n\t});\n}\n/**\n* Utility class for performing content insertion.\n*/\nvar Insertion = class {\n\t/**\n\t* The model in context of which the insertion should be performed.\n\t*/\n\tmodel;\n\t/**\n\t* Batch to which operations will be added.\n\t*/\n\twriter;\n\t/**\n\t* The position at which (or near which) the next node will be inserted.\n\t*/\n\tposition;\n\t/**\n\t* Elements with which the inserted elements can be merged.\n\t*\n\t* ```html\n\t* <p>x^</p><p>y</p> + <p>z</p> (can merge to <p>x</p>)\n\t* <p>x</p><p>^y</p> + <p>z</p> (can merge to <p>y</p>)\n\t* <p>x^y</p> + <p>z</p> (can merge to <p>xy</p> which will be split during the action,\n\t* \t\t\t\t\t\tso both its pieces will be added to this set)\n\t* ```\n\t*/\n\tcanMergeWith;\n\t/**\n\t* Schema of the model.\n\t*/\n\tschema;\n\t/**\n\t* The temporary ModelDocumentFragment used for grouping multiple nodes for single insert operation.\n\t*/\n\t_documentFragment;\n\t/**\n\t* The current position in the temporary ModelDocumentFragment.\n\t*/\n\t_documentFragmentPosition;\n\t/**\n\t* The reference to the first inserted node.\n\t*/\n\t_firstNode = null;\n\t/**\n\t* The reference to the last inserted node.\n\t*/\n\t_lastNode = null;\n\t/**\n\t* The reference to the last auto paragraph node.\n\t*/\n\t_lastAutoParagraph = null;\n\t/**\n\t* The array of nodes that should be cleaned of not allowed attributes and sub-nodes.\n\t*/\n\t_filterAttributesAndChildrenOf = [];\n\t/**\n\t* Beginning of the affected range. See {@link module:engine/model/utils/insertcontent~Insertion#getAffectedRange}.\n\t*/\n\t_affectedStart = null;\n\t/**\n\t* End of the affected range. See {@link module:engine/model/utils/insertcontent~Insertion#getAffectedRange}.\n\t*/\n\t_affectedEnd = null;\n\t_nodeToSelect = null;\n\tconstructor(model, writer, position) {\n\t\tthis.model = model;\n\t\tthis.writer = writer;\n\t\tthis.position = position;\n\t\tthis.canMergeWith = /* @__PURE__ */ new Set([this.position.parent]);\n\t\tthis.schema = model.schema;\n\t\tthis._documentFragment = writer.createDocumentFragment();\n\t\tthis._documentFragmentPosition = writer.createPositionAt(this._documentFragment, 0);\n\t}\n\t/**\n\t* Handles insertion of a set of nodes.\n\t*\n\t* @param nodes Nodes to insert.\n\t*/\n\thandleNodes(nodes) {\n\t\tfor (const node of Array.from(nodes)) if (node.offsetSize > 0) this._handleNode(node);\n\t\tthis._insertPartialFragment();\n\t\tif (this._lastAutoParagraph) this._updateLastNodeFromAutoParagraph(this._lastAutoParagraph);\n\t\tthis._mergeOnRight();\n\t\tthis.schema.removeDisallowedAttributes(this._filterAttributesAndChildrenOf, this.writer);\n\t\tif (this.model._config?.get(\"experimentalFlags.modelInsertContentDeepSchemaVerification\") !== false) this._removeDisallowedChildren(this._filterAttributesAndChildrenOf);\n\t\tthis._filterAttributesAndChildrenOf = [];\n\t}\n\t/**\n\t* Removes disallowed children from nodes that were inserted or modified during insertion.\n\t*/\n\t_removeDisallowedChildren(nodes) {\n\t\tconst nodesArray = Array.from(nodes);\n\t\tfor (const node of nodesArray) {\n\t\t\tif (!node.is(\"element\")) continue;\n\t\t\tconst remove = [];\n\t\t\tconst unwrap = [];\n\t\t\tconst walker = this.writer.createRangeIn(node).getWalker({ ignoreElementEnd: true });\n\t\t\tfor (const { item } of walker) {\n\t\t\t\tconst itemParent = item.parent;\n\t\t\t\tif (!this.schema.checkChild(itemParent, item)) {\n\t\t\t\t\tif (item.is(\"element\") && !this.schema.isObject(item)) {\n\t\t\t\t\t\tunwrap.push(item);\n\t\t\t\t\t\tnodesArray.push(itemParent);\n\t\t\t\t\t} else remove.push(item);\n\t\t\t\t\twalker.jumpTo(this.writer.createPositionAfter(item));\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const item of unwrap) this.writer.unwrap(item);\n\t\t\tfor (const item of remove) this.writer.remove(item);\n\t\t}\n\t}\n\t/**\n\t* Updates the last node after the auto paragraphing.\n\t*\n\t* @param node The last auto paragraphing node.\n\t*/\n\t_updateLastNodeFromAutoParagraph(node) {\n\t\tconst positionAfterLastNode = this.writer.createPositionAfter(this._lastNode);\n\t\tconst positionAfterNode = this.writer.createPositionAfter(node);\n\t\tif (positionAfterNode.isAfter(positionAfterLastNode)) {\n\t\t\tthis._lastNode = node;\n\t\t\t/* v8 ignore if -- @preserve */\n\t\t\tif (this.position.parent != node || !this.position.isAtEnd) throw new CKEditorError(\"insertcontent-invalid-insertion-position\", this);\n\t\t\tthis.position = positionAfterNode;\n\t\t\tthis._setAffectedBoundaries(this.position);\n\t\t}\n\t}\n\t/**\n\t* Returns range to be selected after insertion.\n\t* Returns `null` if there is no valid range to select after insertion.\n\t*/\n\tgetSelectionRange() {\n\t\tif (this._nodeToSelect) return ModelRange._createOn(this._nodeToSelect);\n\t\treturn this.model.schema.getNearestSelectionRange(this.position);\n\t}\n\t/**\n\t* Returns a range which contains all the performed changes. This is a range that, if removed, would return the model to the state\n\t* before the insertion. Returns `null` if no changes were done.\n\t*/\n\tgetAffectedRange() {\n\t\tif (!this._affectedStart) return null;\n\t\treturn new ModelRange(this._affectedStart, this._affectedEnd);\n\t}\n\t/**\n\t* Destroys `Insertion` instance.\n\t*/\n\tdestroy() {\n\t\tif (this._affectedStart) this._affectedStart.detach();\n\t\tif (this._affectedEnd) this._affectedEnd.detach();\n\t}\n\t/**\n\t* Handles insertion of a single node.\n\t*/\n\t_handleNode(node) {\n\t\tif (!this._checkAndSplitToAllowedPosition(node)) {\n\t\t\tif (!this.schema.isObject(node)) this._handleDisallowedNode(node);\n\t\t\treturn;\n\t\t}\n\t\tnode = this._appendToFragment(node);\n\t\tif (!this._firstNode) this._firstNode = node;\n\t\tthis._lastNode = node;\n\t}\n\t/**\n\t* Inserts the temporary ModelDocumentFragment into the model.\n\t*/\n\t_insertPartialFragment() {\n\t\tif (this._documentFragment.isEmpty) return;\n\t\tconst livePosition = ModelLivePosition.fromPosition(this.position, \"toNext\");\n\t\tthis._setAffectedBoundaries(this.position);\n\t\tif (this._documentFragment.getChild(0) == this._firstNode) {\n\t\t\tthis.writer.insert(this._firstNode, this.position);\n\t\t\tthis._mergeOnLeft();\n\t\t\tthis.position = livePosition.toPosition();\n\t\t}\n\t\tif (!this._documentFragment.isEmpty) this.writer.insert(this._documentFragment, this.position);\n\t\tthis._documentFragmentPosition = this.writer.createPositionAt(this._documentFragment, 0);\n\t\tthis.position = livePosition.toPosition();\n\t\tlivePosition.detach();\n\t}\n\t/**\n\t* @param node The disallowed node which needs to be handled.\n\t*/\n\t_handleDisallowedNode(node) {\n\t\tif (node.is(\"element\")) this.handleNodes(node.getChildren());\n\t}\n\t/**\n\t* Append a node to the temporary ModelDocumentFragment.\n\t*\n\t* @param node The node to insert.\n\t*/\n\t_appendToFragment(node) {\n\t\t/* v8 ignore if -- @preserve */\n\t\tif (!this.schema.checkChild(this.position, node))\n /**\n\t\t* Given node cannot be inserted on the given position.\n\t\t*\n\t\t* @error insertcontent-wrong-position\n\t\t* @param {module:engine/model/node~ModelNode} node Node to insert.\n\t\t* @param {module:engine/model/position~ModelPosition} position Position to insert the node at.\n\t\t*/\n\t\tthrow new CKEditorError(\"insertcontent-wrong-position\", this, {\n\t\t\tnode,\n\t\t\tposition: this.position\n\t\t});\n\t\tthis.writer.insert(node, this._documentFragmentPosition);\n\t\tthis._documentFragmentPosition = this._documentFragmentPosition.getShiftedBy(node.offsetSize);\n\t\tif (!node.parent) node = this._documentFragmentPosition.nodeBefore;\n\t\tif (this.schema.isObject(node) && !this.schema.checkChild(this.position, \"$text\")) this._nodeToSelect = node;\n\t\telse this._nodeToSelect = null;\n\t\tthis._filterAttributesAndChildrenOf.push(node);\n\t\treturn node;\n\t}\n\t/**\n\t* Sets `_affectedStart` and `_affectedEnd` to the given `position`. Should be used before a change is done during insertion process to\n\t* mark the affected range.\n\t*\n\t* This method is used before inserting a node or splitting a parent node. `_affectedStart` and `_affectedEnd` are also changed\n\t* during merging, but the logic there is more complicated so it is left out of this function.\n\t*/\n\t_setAffectedBoundaries(position) {\n\t\tif (!this._affectedStart) this._affectedStart = ModelLivePosition.fromPosition(position, \"toPrevious\");\n\t\tif (!this._affectedEnd || this._affectedEnd.isBefore(position)) {\n\t\t\tif (this._affectedEnd) this._affectedEnd.detach();\n\t\t\tthis._affectedEnd = ModelLivePosition.fromPosition(position, \"toNext\");\n\t\t}\n\t}\n\t/**\n\t* Merges the previous sibling of the first node if it should be merged.\n\t*\n\t* After the content was inserted we may try to merge it with its siblings.\n\t* This should happen only if the selection was in those elements initially.\n\t*/\n\t_mergeOnLeft() {\n\t\tconst node = this._firstNode;\n\t\tif (!(node instanceof ModelElement)) return;\n\t\tif (!this._canMergeLeft(node)) return;\n\t\tconst mergePosLeft = ModelLivePosition._createBefore(node);\n\t\tmergePosLeft.stickiness = \"toNext\";\n\t\tconst livePosition = ModelLivePosition.fromPosition(this.position, \"toNext\");\n\t\tif (this._affectedStart.isEqual(mergePosLeft)) {\n\t\t\tthis._affectedStart.detach();\n\t\t\tthis._affectedStart = ModelLivePosition._createAt(mergePosLeft.nodeBefore, \"end\", \"toPrevious\");\n\t\t}\n\t\tif (this._firstNode === this._lastNode) {\n\t\t\tthis._firstNode = mergePosLeft.nodeBefore;\n\t\t\tthis._lastNode = mergePosLeft.nodeBefore;\n\t\t}\n\t\tthis.writer.merge(mergePosLeft);\n\t\tif (mergePosLeft.isEqual(this._affectedEnd) && this._firstNode === this._lastNode) {\n\t\t\tthis._affectedEnd.detach();\n\t\t\tthis._affectedEnd = ModelLivePosition._createAt(mergePosLeft.nodeBefore, \"end\", \"toNext\");\n\t\t}\n\t\tthis.position = livePosition.toPosition();\n\t\tlivePosition.detach();\n\t\tthis._filterAttributesAndChildrenOf.push(this.position.parent);\n\t\tmergePosLeft.detach();\n\t}\n\t/**\n\t* Merges the next sibling of the last node if it should be merged.\n\t*\n\t* After the content was inserted we may try to merge it with its siblings.\n\t* This should happen only if the selection was in those elements initially.\n\t*/\n\t_mergeOnRight() {\n\t\tconst node = this._lastNode;\n\t\tif (!(node instanceof ModelElement)) return;\n\t\tif (!this._canMergeRight(node)) return;\n\t\tconst mergePosRight = ModelLivePosition._createAfter(node);\n\t\tmergePosRight.stickiness = \"toNext\";\n\t\t/* v8 ignore if -- @preserve */\n\t\tif (!this.position.isEqual(mergePosRight))\n /**\n\t\t* An internal error occurred when merging inserted content with its siblings.\n\t\t* The insertion position should equal the merge position.\n\t\t*\n\t\t* If you encountered this error, report it back to the CKEditor 5 team\n\t\t* with as many details as possible regarding the content being inserted and the insertion position.\n\t\t*\n\t\t* @error insertcontent-invalid-insertion-position\n\t\t*/\n\t\tthrow new CKEditorError(\"insertcontent-invalid-insertion-position\", this);\n\t\tthis.position = ModelPosition._createAt(mergePosRight.nodeBefore, \"end\");\n\t\tconst livePosition = ModelLivePosition.fromPosition(this.position, \"toPrevious\");\n\t\tif (this._affectedEnd.isEqual(mergePosRight)) {\n\t\t\tthis._affectedEnd.detach();\n\t\t\tthis._affectedEnd = ModelLivePosition._createAt(mergePosRight.nodeBefore, \"end\", \"toNext\");\n\t\t}\n\t\tif (this._firstNode === this._lastNode) {\n\t\t\tthis._firstNode = mergePosRight.nodeBefore;\n\t\t\tthis._lastNode = mergePosRight.nodeBefore;\n\t\t}\n\t\tthis.writer.merge(mergePosRight);\n\t\tif (mergePosRight.getShiftedBy(-1).isEqual(this._affectedStart) && this._firstNode === this._lastNode) {\n\t\t\tthis._affectedStart.detach();\n\t\t\tthis._affectedStart = ModelLivePosition._createAt(mergePosRight.nodeBefore, 0, \"toPrevious\");\n\t\t}\n\t\tthis.position = livePosition.toPosition();\n\t\tlivePosition.detach();\n\t\tthis._filterAttributesAndChildrenOf.push(this.position.parent);\n\t\tmergePosRight.detach();\n\t}\n\t/**\n\t* Checks whether specified node can be merged with previous sibling element.\n\t*\n\t* @param node The node which could potentially be merged.\n\t*/\n\t_canMergeLeft(node) {\n\t\tconst previousSibling = node.previousSibling;\n\t\treturn previousSibling instanceof ModelElement && this.canMergeWith.has(previousSibling) && this.model.schema.checkMerge(previousSibling, node);\n\t}\n\t/**\n\t* Checks whether specified node can be merged with next sibling element.\n\t*\n\t* @param node The node which could potentially be merged.\n\t*/\n\t_canMergeRight(node) {\n\t\tconst nextSibling = node.nextSibling;\n\t\treturn nextSibling instanceof ModelElement && this.canMergeWith.has(nextSibling) && this.model.schema.checkMerge(node, nextSibling);\n\t}\n\t/**\n\t* Inserts a paragraph and moves the insertion position into it.\n\t*/\n\t_insertAutoParagraph() {\n\t\tthis._insertPartialFragment();\n\t\tconst paragraph = this.writer.createElement(\"paragraph\");\n\t\tthis.writer.insert(paragraph, this.position);\n\t\tthis._setAffectedBoundaries(this.position);\n\t\tthis._lastAutoParagraph = paragraph;\n\t\tthis.position = this.writer.createPositionAt(paragraph, 0);\n\t}\n\t/**\n\t* @returns Whether an allowed position was found.\n\t* `false` is returned if the node isn't allowed at any position up in the tree, `true` if was.\n\t*/\n\t_checkAndSplitToAllowedPosition(node) {\n\t\tconst allowedIn = this._getAllowedIn(this.position.parent, node);\n\t\tif (!allowedIn) return false;\n\t\tif (allowedIn != this.position.parent) this._insertPartialFragment();\n\t\twhile (allowedIn != this.position.parent) if (this.position.isAtStart) {\n\t\t\tconst parent = this.position.parent;\n\t\t\tthis.position = this.writer.createPositionBefore(parent);\n\t\t\tif (parent.isEmpty && parent.parent === allowedIn) this.writer.remove(parent);\n\t\t} else if (this.position.isAtEnd) this.position = this.writer.createPositionAfter(this.position.parent);\n\t\telse {\n\t\t\tconst tempPos = this.writer.createPositionAfter(this.position.parent);\n\t\t\tthis._setAffectedBoundaries(this.position);\n\t\t\tthis.writer.split(this.position);\n\t\t\tthis.position = tempPos;\n\t\t\tthis.canMergeWith.add(this.position.nodeAfter);\n\t\t}\n\t\tif (!this.schema.checkChild(this.position.parent, node)) this._insertAutoParagraph();\n\t\treturn true;\n\t}\n\t/**\n\t* Gets the element in which the given node is allowed. It checks the passed element and all its ancestors.\n\t*\n\t* It also verifies if auto-paragraphing could help.\n\t*\n\t* @param contextElement The element in which context the node should be checked.\n\t* @param childNode The node to check.\n\t*/\n\t_getAllowedIn(contextElement, childNode) {\n\t\tconst context = this.schema.createContext(contextElement);\n\t\tif (this.schema.checkChild(context, childNode)) return contextElement;\n\t\tif (this.schema.checkChild(context, \"paragraph\") && this.schema.checkChild(context.push(\"paragraph\"), childNode)) return contextElement;\n\t\tif (this.schema.isLimit(contextElement)) return null;\n\t\treturn this._getAllowedIn(contextElement.parent, childNode);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Inserts an {@glink framework/deep-dive/schema#object-elements object element} at a specific position in the editor content.\n*\n* **Note:** Use {@link module:engine/model/model~Model#insertObject} instead of this function.\n* This function is only exposed to be reusable in algorithms which change the {@link module:engine/model/model~Model#insertObject}\n* method's behavior.\n*\n* **Note**: For more documentation and examples, see {@link module:engine/model/model~Model#insertObject}.\n*\n* @param model The model in context of which the insertion should be performed.\n* @param object An object to be inserted into the model document.\n* @param selectable A selectable where the content should be inserted. If not specified, the current\n* {@link module:engine/model/document~ModelDocument#selection document selection} will be used instead.\n* @param options Additional options.\n* @param options.findOptimalPosition An option that, when set, adjusts the insertion position (relative to\n* `selectable` and `placeOrOffset`) so that the content of `selectable` is not split upon insertion (a.k.a. non-destructive insertion).\n* * When `'auto'`, the algorithm will decide whether to insert the object before or after `selectable` to avoid content splitting.\n* * When `'before'`, the closest position before `selectable` will be used that will not result in content splitting.\n* * When `'after'`, the closest position after `selectable` will be used that will not result in content splitting.\n*\n* Note that this option works only for block objects. Inline objects are inserted into text and do not split blocks.\n* @param options.setSelection An option that, when set, moves the\n* {@link module:engine/model/document~ModelDocument#selection document selection} after inserting the object.\n* * When `'on'`, the document selection will be set on the inserted object.\n* * When `'after'`, the document selection will move to the closest text node after the inserted object. If there is no\n* such text node, a paragraph will be created and the document selection will be moved inside it.\n* @returns A range which contains all the performed changes. This is a range that, if removed,\n* would return the model to the state before the insertion. If no changes were preformed by `insertObject()`, returns a range collapsed\n* at the insertion position.\n*/\nfunction insertObject(model, object, selectable, options = {}) {\n\tif (!model.schema.isObject(object))\n /**\n\t* Tried to insert an element with {@link module:engine/model/utils/insertobject insertObject()} function\n\t* that is not defined as an object in schema.\n\t* See {@link module:engine/model/schema~ModelSchemaItemDefinition#isObject `SchemaItemDefinition`}.\n\t* If you want to insert content that is not an object you might want to use\n\t* {@link module:engine/model/utils/insertcontent insertContent()} function.\n\t* @error insertobject-element-not-an-object\n\t*/\n\tthrow new CKEditorError(\"insertobject-element-not-an-object\", model, { object });\n\tconst originalSelection = selectable ? selectable : model.document.selection;\n\tlet insertionSelection = originalSelection;\n\tif (options.findOptimalPosition && model.schema.isBlock(object)) insertionSelection = model.createSelection(model.schema.findOptimalInsertionRange(originalSelection, options.findOptimalPosition));\n\tconst firstSelectedBlock = first(originalSelection.getSelectedBlocks());\n\tconst attributesToCopy = {};\n\tif (firstSelectedBlock) Object.assign(attributesToCopy, model.schema.getAttributesWithProperty(firstSelectedBlock, \"copyOnReplace\", true));\n\treturn model.change((writer) => {\n\t\tif (!insertionSelection.isCollapsed) model.deleteContent(insertionSelection, { doNotAutoparagraph: true });\n\t\tlet elementToInsert = object;\n\t\tconst insertionPositionParent = insertionSelection.anchor.parent;\n\t\tconst context = model.schema.createContext(insertionPositionParent);\n\t\tif (!model.schema.checkChild(context, object) && model.schema.checkChild(context, \"paragraph\") && model.schema.checkChild(context.push(\"paragraph\"), object)) {\n\t\t\telementToInsert = writer.createElement(\"paragraph\");\n\t\t\twriter.insert(object, elementToInsert);\n\t\t}\n\t\tmodel.schema.setAllowedAttributes(elementToInsert, attributesToCopy, writer);\n\t\tconst affectedRange = model.insertContent(elementToInsert, insertionSelection);\n\t\tif (affectedRange.isCollapsed) return affectedRange;\n\t\tif (options.setSelection) updateSelection(writer, object, options.setSelection, attributesToCopy);\n\t\treturn affectedRange;\n\t});\n}\n/**\n* Updates document selection based on given `place` parameter in relation to `contextElement` element.\n*\n* @param writer An instance of the model writer.\n* @param contextElement An element to set the attributes on.\n* @param place The place where selection should be set in relation to the `contextElement` element.\n* Value `on` will set selection on the passed `contextElement`. Value `after` will set selection after `contextElement`.\n* @param attributes Attributes keys and values to set on a paragraph that this function can create when\n* `place` parameter is equal to `after` but there is no element with `$text` node to set selection in.\n*/\nfunction updateSelection(writer, contextElement, place, paragraphAttributes) {\n\tconst model = writer.model;\n\tif (place == \"on\") {\n\t\twriter.setSelection(contextElement, \"on\");\n\t\treturn;\n\t}\n\tif (place != \"after\")\n /**\n\t* The unsupported `options.setSelection` parameter was passed\n\t* to the {@link module:engine/model/utils/insertobject insertObject()} function.\n\t* Check the {@link module:engine/model/utils/insertobject insertObject()} API documentation for allowed\n\t* `options.setSelection` parameter values.\n\t*\n\t* @error insertobject-invalid-place-parameter-value\n\t*/\n\tthrow new CKEditorError(\"insertobject-invalid-place-parameter-value\", model);\n\tlet nextElement = contextElement.nextSibling;\n\tif (model.schema.isInline(contextElement)) {\n\t\twriter.setSelection(contextElement, \"after\");\n\t\treturn;\n\t}\n\tif (!(nextElement && model.schema.checkChild(nextElement, \"$text\")) && model.schema.checkChild(contextElement.parent, \"paragraph\")) {\n\t\tnextElement = writer.createElement(\"paragraph\");\n\t\tmodel.schema.setAllowedAttributes(nextElement, paragraphAttributes, writer);\n\t\tmodel.insertContent(nextElement, writer.createPositionAfter(contextElement));\n\t}\n\tif (nextElement) writer.setSelection(nextElement, 0);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/utils/modifyselection\n*/\nconst wordBoundaryCharacters = \" ,.?!:;\\\"-()\";\n/**\n* Modifies the selection. Currently, the supported modifications are:\n*\n* * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`.\n* Possible values for `unit` are:\n* * `'character'` (default) - moves selection by one user-perceived character. In most cases this means moving by one\n* character in `String` sense. However, unicode also defines \"combing marks\". These are special symbols, that combines\n* with a symbol before it (\"base character\") to create one user-perceived character. For example, `q̣̇` is a normal\n* letter `q` with two \"combining marks\": upper dot (`Ux0307`) and lower dot (`Ux0323`). For most actions, i.e. extending\n* selection by one position, it is correct to include both \"base character\" and all of it's \"combining marks\". That is\n* why `'character'` value is most natural and common method of modifying selection.\n* * `'codePoint'` - moves selection by one unicode code point. In contrary to, `'character'` unit, this will insert\n* selection between \"base character\" and \"combining mark\", because \"combining marks\" have their own unicode code points.\n* However, for technical reasons, unicode code points with values above `UxFFFF` are represented in native `String` by\n* two characters, called \"surrogate pairs\". Halves of \"surrogate pairs\" have a meaning only when placed next to each other.\n* For example `𨭎` is represented in `String` by `\\uD862\\uDF4E`. Both `\\uD862` and `\\uDF4E` do not have any meaning\n* outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection\n* extension will include whole \"surrogate pair\".\n* * `'word'` - moves selection by a whole word.\n*\n* **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n*\n* **Note:** Use {@link module:engine/model/model~Model#modifySelection} instead of this function.\n* This function is only exposed to be reusable in algorithms\n* which change the {@link module:engine/model/model~Model#modifySelection}\n* method's behavior.\n*\n* @param model The model in context of which the selection modification should be performed.\n* @param selection The selection to modify.\n* @param options.direction The direction in which the selection should be modified. Default 'forward'.\n* @param options.unit The unit by which selection should be modified. Default 'character'.\n* @param options.treatEmojiAsSingleUnit Whether multi-characer emoji sequences should be handled as single unit.\n* @internal\n*/\nfunction modifySelection(model, selection, options = {}) {\n\tconst schema = model.schema;\n\tconst isForward = options.direction != \"backward\";\n\tconst unit = options.unit ? options.unit : \"character\";\n\tconst treatEmojiAsSingleUnit = !!options.treatEmojiAsSingleUnit;\n\tconst focus = selection.focus;\n\tconst walker = new ModelTreeWalker({\n\t\tboundaries: getSearchRange(focus, isForward),\n\t\tsingleCharacters: true,\n\t\tdirection: isForward ? \"forward\" : \"backward\"\n\t});\n\tconst data = {\n\t\twalker,\n\t\tschema,\n\t\tisForward,\n\t\tunit,\n\t\ttreatEmojiAsSingleUnit\n\t};\n\tlet next;\n\twhile (next = walker.next()) {\n\t\tif (next.done) return;\n\t\tconst position = tryExtendingTo(data, next.value);\n\t\tif (position) {\n\t\t\tif (selection instanceof ModelDocumentSelection) model.change((writer) => {\n\t\t\t\twriter.setSelectionFocus(position);\n\t\t\t});\n\t\t\telse selection.setFocus(position);\n\t\t\treturn;\n\t\t}\n\t}\n}\n/**\n* Checks whether the selection can be extended to the the walker's next value (next position).\n*/\nfunction tryExtendingTo(data, value) {\n\tconst { isForward, walker, unit, schema, treatEmojiAsSingleUnit } = data;\n\tconst { type, item, nextPosition } = value;\n\tif (type == \"text\") {\n\t\tif (data.unit === \"word\") return getCorrectWordBreakPosition(walker, isForward);\n\t\treturn getCorrectPosition(walker, unit, treatEmojiAsSingleUnit);\n\t}\n\tif (type == (isForward ? \"elementStart\" : \"elementEnd\")) {\n\t\tif (schema.isSelectable(item)) return ModelPosition._createAt(item, isForward ? \"after\" : \"before\");\n\t\tif (schema.checkChild(nextPosition, \"$text\")) return nextPosition;\n\t} else {\n\t\tif (schema.isLimit(item)) {\n\t\t\twalker.skip(() => true);\n\t\t\treturn;\n\t\t}\n\t\tif (schema.checkChild(nextPosition, \"$text\")) return nextPosition;\n\t}\n}\n/**\n* Finds a correct position by walking in a text node and checking whether selection can be extended to given position\n* or should be extended further.\n*/\nfunction getCorrectPosition(walker, unit, treatEmojiAsSingleUnit) {\n\tconst textNode = walker.position.textNode;\n\tif (textNode) {\n\t\tconst data = textNode.data;\n\t\tlet offset = walker.position.offset - textNode.startOffset;\n\t\twhile (isInsideSurrogatePair(data, offset) || unit == \"character\" && isInsideCombinedSymbol(data, offset) || treatEmojiAsSingleUnit && isInsideEmojiSequence(data, offset)) {\n\t\t\twalker.next();\n\t\t\toffset = walker.position.offset - textNode.startOffset;\n\t\t}\n\t}\n\treturn walker.position;\n}\n/**\n* Finds a correct position of a word break by walking in a text node and checking whether selection can be extended to given position\n* or should be extended further.\n*/\nfunction getCorrectWordBreakPosition(walker, isForward) {\n\tlet textNode = walker.position.textNode;\n\tif (!textNode) textNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;\n\twhile (textNode && textNode.is(\"$text\")) {\n\t\tconst offset = walker.position.offset - textNode.startOffset;\n\t\tif (isAtNodeBoundary(textNode, offset, isForward)) textNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;\n\t\telse if (isAtWordBoundary(textNode.data, offset, isForward)) break;\n\t\telse walker.next();\n\t}\n\treturn walker.position;\n}\nfunction getSearchRange(start, isForward) {\n\tconst root = start.root;\n\tconst searchEnd = ModelPosition._createAt(root, isForward ? \"end\" : 0);\n\tif (isForward) return new ModelRange(start, searchEnd);\n\telse return new ModelRange(searchEnd, start);\n}\n/**\n* Checks if selection is on word boundary.\n*/\nfunction isAtWordBoundary(data, offset, isForward) {\n\tconst offsetToCheck = offset + (isForward ? 0 : -1);\n\treturn wordBoundaryCharacters.includes(data.charAt(offsetToCheck));\n}\n/**\n* Checks if selection is on node boundary.\n*/\nfunction isAtNodeBoundary(textNode, offset, isForward) {\n\treturn offset === (isForward ? textNode.offsetSize : 0);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/model/model\n*/\nconst ModelBase = /* #__PURE__ */ ObservableMixin();\n/**\n* Editor's data model. Read about the model in the\n* {@glink framework/architecture/editing-engine engine architecture} guide.\n*/\nvar Model = class extends ModelBase {\n\t/**\n\t* Model's marker collection.\n\t*/\n\tmarkers;\n\t/**\n\t* Model's document.\n\t*/\n\tdocument;\n\t/**\n\t* Model's schema.\n\t*/\n\tschema;\n\t/**\n\t* Stores all configurations specific to editor instance.\n\t*\n\t* @internal\n\t*/\n\t_config;\n\t/**\n\t* All callbacks added by {@link module:engine/model/model~Model#change} or\n\t* {@link module:engine/model/model~Model#enqueueChange} methods waiting to be executed.\n\t*/\n\t_pendingChanges;\n\t/**\n\t* The last created and currently used writer instance.\n\t*/\n\t_currentWriter;\n\tconstructor(config) {\n\t\tsuper();\n\t\tthis.markers = new MarkerCollection();\n\t\tthis.document = new ModelDocument(this);\n\t\tthis.schema = new ModelSchema();\n\t\tthis._config = config;\n\t\tthis._pendingChanges = [];\n\t\tthis._currentWriter = null;\n\t\t[\n\t\t\t\"deleteContent\",\n\t\t\t\"modifySelection\",\n\t\t\t\"getSelectedContent\",\n\t\t\t\"applyOperation\"\n\t\t].forEach((methodName) => this.decorate(methodName));\n\t\tthis.on(\"applyOperation\", (evt, args) => {\n\t\t\targs[0]._validate();\n\t\t}, { priority: \"highest\" });\n\t\tthis.schema.register(\"$root\", { isLimit: true });\n\t\tthis.schema.register(\"$inlineRoot\", {\n\t\t\tallowContentOf: \"$block\",\n\t\t\tallowAttributesOf: \"$root\",\n\t\t\tisLimit: true\n\t\t});\n\t\tthis.schema.register(\"$container\", { allowIn: [\"$root\", \"$container\"] });\n\t\tthis.schema.register(\"$block\", {\n\t\t\tallowIn: [\"$root\", \"$container\"],\n\t\t\tisBlock: true\n\t\t});\n\t\tthis.schema.register(\"$blockObject\", {\n\t\t\tallowWhere: \"$block\",\n\t\t\tisBlock: true,\n\t\t\tisObject: true\n\t\t});\n\t\tthis.schema.register(\"$inlineObject\", {\n\t\t\tallowWhere: \"$text\",\n\t\t\tallowAttributesOf: \"$text\",\n\t\t\tisInline: true,\n\t\t\tisObject: true\n\t\t});\n\t\tthis.schema.register(\"$text\", {\n\t\t\tallowIn: \"$block\",\n\t\t\tisInline: true,\n\t\t\tisContent: true\n\t\t});\n\t\tthis.schema.register(\"$clipboardHolder\", {\n\t\t\tallowContentOf: [\"$root\", \"$inlineRoot\"],\n\t\t\tallowChildren: \"$text\",\n\t\t\tisLimit: true\n\t\t});\n\t\tthis.schema.register(\"$documentFragment\", {\n\t\t\tallowContentOf: [\"$root\", \"$inlineRoot\"],\n\t\t\tallowChildren: \"$text\",\n\t\t\tisLimit: true\n\t\t});\n\t\tthis.schema.register(\"$marker\");\n\t\tthis.schema.addChildCheck(() => true, \"$marker\");\n\t\tinjectSelectionPostFixer(this);\n\t\tthis.document.registerPostFixer(autoParagraphEmptyRoots);\n\t\tthis.on(\"insertContent\", (evt, [content, selectable]) => {\n\t\t\tevt.return = insertContent(this, content, selectable);\n\t\t});\n\t\tthis.on(\"insertObject\", (evt, [element, selection, options]) => {\n\t\t\tevt.return = insertObject(this, element, selection, options);\n\t\t});\n\t\tthis.on(\"canEditAt\", (evt) => {\n\t\t\tconst canEditAt = !this.document.isReadOnly;\n\t\t\tevt.return = canEditAt;\n\t\t\tif (!canEditAt) evt.stop();\n\t\t});\n\t}\n\t/**\n\t* The `change()` method is the primary way of changing the model. You should use it to modify all document nodes\n\t* (including detached nodes – i.e. nodes not added to the {@link module:engine/model/model~Model#document model document}),\n\t* the {@link module:engine/model/document~ModelDocument#selection document's selection}, and\n\t* {@link module:engine/model/model~Model#markers model markers}.\n\t*\n\t* ```ts\n\t* model.change( writer => {\n\t* \twriter.insertText( 'foo', paragraph, 'end' );\n\t* } );\n\t* ```\n\t*\n\t* All changes inside the change block use the same {@link module:engine/model/batch~Batch} so they are combined\n\t* into a single undo step.\n\t*\n\t* ```ts\n\t* model.change( writer => {\n\t* \twriter.insertText( 'foo', paragraph, 'end' ); // foo.\n\t*\n\t* \tmodel.change( writer => {\n\t* \t\twriter.insertText( 'bar', paragraph, 'end' ); // foobar.\n\t* \t} );\n\t*\n\t* \twriter.insertText( 'bom', paragraph, 'end' ); // foobarbom.\n\t* } );\n\t* ```\n\t*\n\t* The callback of the `change()` block is executed synchronously.\n\t*\n\t* You can also return a value from the change block.\n\t*\n\t* ```ts\n\t* const img = model.change( writer => {\n\t* \treturn writer.createElement( 'img' );\n\t* } );\n\t* ```\n\t*\n\t* @see #enqueueChange\n\t* @typeParam TReturn The return type of the provided callback.\n\t* @param callback Callback function which may modify the model.\n\t*/\n\tchange(callback) {\n\t\ttry {\n\t\t\tif (this._pendingChanges.length === 0) {\n\t\t\t\tthis._pendingChanges.push({\n\t\t\t\t\tbatch: new Batch(),\n\t\t\t\t\tcallback\n\t\t\t\t});\n\t\t\t\treturn this._runPendingChanges()[0];\n\t\t\t} else return callback(this._currentWriter);\n\t\t} catch (err) {\n\t\t\tCKEditorError.rethrowUnexpectedError(err, this);\n\t\t}\n\t}\n\tenqueueChange(batchOrType, callback) {\n\t\ttry {\n\t\t\tif (!batchOrType) batchOrType = new Batch();\n\t\t\telse if (typeof batchOrType === \"function\") {\n\t\t\t\tcallback = batchOrType;\n\t\t\t\tbatchOrType = new Batch();\n\t\t\t} else if (!(batchOrType instanceof Batch)) batchOrType = new Batch(batchOrType);\n\t\t\tthis._pendingChanges.push({\n\t\t\t\tbatch: batchOrType,\n\t\t\t\tcallback\n\t\t\t});\n\t\t\tif (this._pendingChanges.length == 1) this._runPendingChanges();\n\t\t} catch (err) {\n\t\t\tCKEditorError.rethrowUnexpectedError(err, this);\n\t\t}\n\t}\n\t/**\n\t* {@link module:utils/observablemixin~Observable#decorate Decorated} function for applying\n\t* {@link module:engine/model/operation/operation~Operation operations} to the model.\n\t*\n\t* This is a low-level way of changing the model. It is exposed for very specific use cases (like the undo feature).\n\t* Normally, to modify the model, you will want to use {@link module:engine/model/writer~ModelWriter `Writer`}.\n\t* See also {@glink framework/architecture/editing-engine#changing-the-model Changing the model} section\n\t* of the {@glink framework/architecture/editing-engine Editing architecture} guide.\n\t*\n\t* @param operation The operation to apply.\n\t*/\n\tapplyOperation(operation) {\n\t\toperation._execute();\n\t}\n\t/**\n\t* Inserts content at the position in the editor specified by the selection, as one would expect the paste\n\t* functionality to work.\n\t*\n\t* **Note**: If you want to insert an {@glink framework/deep-dive/schema#object-elements object element}\n\t* (e.g. a {@link module:widget/utils~toWidget widget}), see {@link #insertObject} instead.\n\t*\n\t* This is a high-level method. It takes the {@link #schema schema} into consideration when inserting\n\t* the content, clears the given selection's content before inserting nodes and moves the selection\n\t* to its target position at the end of the process.\n\t* It can split elements, merge them, wrap bare text nodes with paragraphs, etc. &ndash; just like the\n\t* pasting feature should do.\n\t*\n\t* For lower-level methods see {@link module:engine/model/writer~ModelWriter `Writer`}.\n\t*\n\t* This method, unlike {@link module:engine/model/writer~ModelWriter `Writer`}'s methods, does not have to be used\n\t* inside a {@link #change `change()` block}.\n\t*\n\t* # Conversion and schema\n\t*\n\t* Inserting elements and text nodes into the model is not enough to make CKEditor 5 render that content\n\t* to the user. CKEditor 5 implements a model-view-controller architecture and what `model.insertContent()` does\n\t* is only adding nodes to the model. Additionally, you need to define\n\t* {@glink framework/architecture/editing-engine#conversion converters} between the model and view\n\t* and define those nodes in the {@glink framework/architecture/editing-engine#schema schema}.\n\t*\n\t* So, while this method may seem similar to CKEditor 4 `editor.insertHtml()` (in fact, both methods\n\t* are used for paste-like content insertion), the CKEditor 5 method cannot be use to insert arbitrary HTML\n\t* unless converters are defined for all elements and attributes in that HTML.\n\t*\n\t* # Examples\n\t*\n\t* Using `insertContent()` with a manually created model structure:\n\t*\n\t* ```ts\n\t* // Let's create a document fragment containing such content as:\n\t* //\n\t* // <paragraph>foo</paragraph>\n\t* // <blockQuote>\n\t* // <paragraph>bar</paragraph>\n\t* // </blockQuote>\n\t* const docFrag = editor.model.change( writer => {\n\t* \tconst p1 = writer.createElement( 'paragraph' );\n\t* \tconst p2 = writer.createElement( 'paragraph' );\n\t* \tconst blockQuote = writer.createElement( 'blockQuote' );\n\t* \tconst docFrag = writer.createDocumentFragment();\n\t*\n\t* \twriter.append( p1, docFrag );\n\t* \twriter.append( blockQuote, docFrag );\n\t* \twriter.append( p2, blockQuote );\n\t* \twriter.insertText( 'foo', p1 );\n\t* \twriter.insertText( 'bar', p2 );\n\t*\n\t* \treturn docFrag;\n\t* } );\n\t*\n\t* // insertContent() does not have to be used in a change() block. It can, though,\n\t* // so this code could be moved to the callback defined above.\n\t* editor.model.insertContent( docFrag );\n\t* ```\n\t*\n\t* Using `insertContent()` with an HTML string converted to a model document fragment (similar to the pasting mechanism):\n\t*\n\t* ```ts\n\t* // You can create your own HtmlDataProcessor instance or use editor.data.processor\n\t* // if you have not overridden the default one (which is the HtmlDataProcessor instance).\n\t* const htmlDP = new HtmlDataProcessor( viewDocument );\n\t*\n\t* // Convert an HTML string to a view document fragment:\n\t* const viewFragment = htmlDP.toView( htmlString );\n\t*\n\t* // Convert the view document fragment to a model document fragment\n\t* // in the context of $root. This conversion takes the schema into\n\t* // account so if, for example, the view document fragment contained a bare text node,\n\t* // this text node cannot be a child of $root, so it will be automatically\n\t* // wrapped with a <paragraph>. You can define the context yourself (in the second parameter),\n\t* // and e.g. convert the content like it would happen in a <paragraph>.\n\t* // Note: The clipboard feature uses a custom context called $clipboardHolder\n\t* // which has a loosened schema.\n\t* const modelFragment = editor.data.toModel( viewFragment );\n\t*\n\t* editor.model.insertContent( modelFragment );\n\t* ```\n\t*\n\t* By default this method will use the document selection but it can also be used with a position, range or selection instance.\n\t*\n\t* ```ts\n\t* // Insert text at the current document selection position.\n\t* editor.model.change( writer => {\n\t* \teditor.model.insertContent( writer.createText( 'x' ) );\n\t* } );\n\t*\n\t* // Insert text at a given position - the document selection will not be modified.\n\t* editor.model.change( writer => {\n\t* \teditor.model.insertContent( writer.createText( 'x' ), doc.getRoot(), 2 );\n\t*\n\t* \t// Which is a shorthand for:\n\t* \teditor.model.insertContent( writer.createText( 'x' ), writer.createPositionAt( doc.getRoot(), 2 ) );\n\t* } );\n\t* ```\n\t*\n\t* If you want the document selection to be moved to the inserted content, use the\n\t* {@link module:engine/model/writer~ModelWriter#setSelection `setSelection()`} method of the writer after inserting\n\t* the content:\n\t*\n\t* ```ts\n\t* editor.model.change( writer => {\n\t* \tconst paragraph = writer.createElement( 'paragraph' );\n\t*\n\t* \t// Insert an empty paragraph at the beginning of the root.\n\t* \teditor.model.insertContent( paragraph, writer.createPositionAt( editor.model.document.getRoot(), 0 ) );\n\t*\n\t* \t// Move the document selection to the inserted paragraph.\n\t* \twriter.setSelection( paragraph, 'in' );\n\t* } );\n\t* ```\n\t*\n\t* If an instance of the {@link module:engine/model/selection~ModelSelection model selection} is passed as `selectable`,\n\t* the new content will be inserted at the passed selection (instead of document selection):\n\t*\n\t* ```ts\n\t* editor.model.change( writer => {\n\t* \t// Create a selection in a paragraph that will be used as a place of insertion.\n\t* \tconst selection = writer.createSelection( paragraph, 'in' );\n\t*\n\t* \t// Insert the new text at the created selection.\n\t* \teditor.model.insertContent( writer.createText( 'x' ), selection );\n\t*\n\t* \t// insertContent() modifies the passed selection instance so it can be used to set the document selection.\n\t* \t// Note: This is not necessary when you passed the document selection to insertContent().\n\t* \twriter.setSelection( selection );\n\t* } );\n\t* ```\n\t*\n\t* @fires insertContent\n\t* @param content The content to insert.\n\t* @param selectable The selection into which the content should be inserted.\n\t* If not provided the current model document selection will be used.\n\t* @param placeOrOffset To be used when a model item was passed as `selectable`.\n\t* This param defines a position in relation to that item.\n\t* at the insertion position.\n\t*/\n\tinsertContent(content, selectable, placeOrOffset, ...rest) {\n\t\tconst selection = normalizeSelectable(selectable, placeOrOffset);\n\t\treturn this.fire(\"insertContent\", [\n\t\t\tcontent,\n\t\t\tselection,\n\t\t\tplaceOrOffset,\n\t\t\t...rest\n\t\t]);\n\t}\n\t/**\n\t* Inserts an {@glink framework/deep-dive/schema#object-elements object element} at a specific position in the editor content.\n\t*\n\t* This is a high-level API:\n\t* * It takes the {@link #schema schema} into consideration,\n\t* * It clears the content of passed `selectable` before inserting,\n\t* * It can move the selection at the end of the process,\n\t* * It will copy the selected block's attributes to preserve them upon insertion,\n\t* * It can split elements or wrap inline objects with paragraphs if they are not allowed in target position,\n\t* * etc.\n\t*\n\t* # Notes\n\t*\n\t* * If you want to insert a non-object content, see {@link #insertContent} instead.\n\t* * For lower-level API, see {@link module:engine/model/writer~ModelWriter `Writer`}.\n\t* * Unlike {@link module:engine/model/writer~ModelWriter `Writer`}, this method does not have to be used inside\n\t* a {@link #change `change()` block}.\n\t* * Inserting object into the model is not enough to make CKEditor 5 render that content to the user.\n\t* CKEditor 5 implements a model-view-controller architecture and what `model.insertObject()` does\n\t* is only adding nodes to the model. Additionally, you need to define\n\t* {@glink framework/architecture/editing-engine#conversion converters} between the model and view\n\t* and define those nodes in the {@glink framework/architecture/editing-engine#schema schema}.\n\t*\n\t* # Examples\n\t*\n\t* Use the following code to insert an object at the current selection and keep the selection on the inserted element:\n\t*\n\t* ```ts\n\t* const rawHtmlEmbedElement = writer.createElement( 'rawHtml' );\n\t*\n\t* model.insertObject( rawHtmlEmbedElement, null, null, {\n\t* \tsetSelection: 'on'\n\t* } );\n\t* ```\n\t*\n\t* Use the following code to insert an object at the current selection and nudge the selection after the inserted object:\n\t*\n\t* ```ts\n\t* const pageBreakElement = writer.createElement( 'pageBreak' );\n\t*\n\t* model.insertObject( pageBreakElement, null, null, {\n\t* \tsetSelection: 'after'\n\t* } );\n\t* ```\n\t*\n\t* Use the following code to insert an object at the current selection and avoid splitting the content (non-destructive insertion):\n\t*\n\t* ```ts\n\t* const tableElement = writer.createElement( 'table' );\n\t*\n\t* model.insertObject( tableElement, null, null, {\n\t* \tfindOptimalPosition: 'auto'\n\t* } );\n\t* ```\n\t*\n\t* Use the following code to insert an object at the specific range (also: replace the content of the range):\n\t*\n\t* ```ts\n\t* const tableElement = writer.createElement( 'table' );\n\t* const range = model.createRangeOn( model.document.getRoot().getChild( 1 ) );\n\t*\n\t* model.insertObject( tableElement, range );\n\t* ```\n\t*\n\t* @param element An object to be inserted into the model document.\n\t* @param selectable A selectable where the content should be inserted. If not specified, the current\n\t* {@link module:engine/model/document~ModelDocument#selection document selection} will be used instead.\n\t* @param placeOrOffset Specifies the exact place or offset for the insertion to take place, relative to `selectable`.\n\t* @param options Additional options.\n\t* @param options.findOptimalPosition An option that, when set, adjusts the insertion position (relative to\n\t* `selectable` and `placeOrOffset`) so that the content of `selectable` is not split upon insertion (a.k.a. non-destructive insertion).\n\t* * When `'auto'`, the algorithm will decide whether to insert the object before or after `selectable` to avoid content splitting.\n\t* * When `'before'`, the closest position before `selectable` will be used that will not result in content splitting.\n\t* * When `'after'`, the closest position after `selectable` will be used that will not result in content splitting.\n\t*\n\t* Note that this option only works for block objects. Inline objects are inserted into text and do not split blocks.\n\t* @param options.setSelection An option that, when set, moves the\n\t* {@link module:engine/model/document~ModelDocument#selection document selection} after inserting the object.\n\t* * When `'on'`, the document selection will be set on the inserted object.\n\t* * When `'after'`, the document selection will move to the closest text node after the inserted object. If there is no\n\t* such text node, a paragraph will be created and the document selection will be moved inside it.\n\t* at the insertion position.\n\t*/\n\tinsertObject(element, selectable, placeOrOffset, options, ...rest) {\n\t\tconst selection = normalizeSelectable(selectable, placeOrOffset);\n\t\treturn this.fire(\"insertObject\", [\n\t\t\telement,\n\t\t\tselection,\n\t\t\toptions,\n\t\t\toptions,\n\t\t\t...rest\n\t\t]);\n\t}\n\t/**\n\t* Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n\t*\n\t* **Note:** For the sake of predictability, the resulting selection should always be collapsed.\n\t* In cases where a feature wants to modify deleting behavior so selection isn't collapsed\n\t* (e.g. a table feature may want to keep row selection after pressing <kbd>Backspace</kbd>),\n\t* then that behavior should be implemented in the view's listener. At the same time, the table feature\n\t* will need to modify this method's behavior too, e.g. to \"delete contents and then collapse\n\t* the selection inside the last selected cell\" or \"delete the row and collapse selection somewhere near\".\n\t* That needs to be done in order to ensure that other features which use `deleteContent()` will work well with tables.\n\t*\n\t* @fires deleteContent\n\t* @param selection Selection of which the content should be deleted.\n\t* @param options.leaveUnmerged Whether to merge elements after removing the content of the selection.\n\t*\n\t* For example `<heading1>x[x</heading1><paragraph>y]y</paragraph>` will become:\n\t*\n\t* * `<heading1>x^y</heading1>` with the option disabled (`leaveUnmerged == false`)\n\t* * `<heading1>x^</heading1><paragraph>y</paragraph>` with enabled (`leaveUnmerged == true`).\n\t*\n\t* Note: {@link module:engine/model/schema~ModelSchema#isObject object} and {@link module:engine/model/schema~ModelSchema#isLimit limit}\n\t* elements will not be merged.\n\t*\n\t* @param options.doNotResetEntireContent Whether to skip replacing the entire content with a\n\t* paragraph when the entire content was selected.\n\t*\n\t* For example `<heading1>[x</heading1><paragraph>y]</paragraph>` will become:\n\t*\n\t* * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)\n\t* * `<heading1>^</heading1>` with enabled (`doNotResetEntireContent == true`)\n\t*\n\t* @param options.doNotAutoparagraph Whether to create a paragraph if after content deletion selection is moved\n\t* to a place where text cannot be inserted.\n\t*\n\t* For example `<paragraph>x</paragraph>[<imageBlock src=\"foo.jpg\"></imageBlock>]` will become:\n\t*\n\t* * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`)\n\t* * `<paragraph>x[]</paragraph>` with the option enabled (`doNotAutoparagraph == true`).\n\t*\n\t* **Note:** if there is no valid position for the selection, the paragraph will always be created:\n\t*\n\t* `[<imageBlock src=\"foo.jpg\"></imageBlock>]` -> `<paragraph>[]</paragraph>`.\n\t*\n\t* @param options.direction The direction in which the content is being consumed.\n\t* Deleting backward corresponds to using the <kbd>Backspace</kbd> key, while deleting content forward corresponds to\n\t* the <kbd>Shift</kbd>+<kbd>Backspace</kbd> keystroke.\n\t*/\n\tdeleteContent(selection, options) {\n\t\tdeleteContent(this, selection, options);\n\t}\n\t/**\n\t* Modifies the selection. Currently, the supported modifications are:\n\t*\n\t* * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`.\n\t* Possible values for `unit` are:\n\t* * `'character'` (default) - moves selection by one user-perceived character. In most cases this means moving by one\n\t* character in `String` sense. However, unicode also defines \"combing marks\". These are special symbols, that combines\n\t* with a symbol before it (\"base character\") to create one user-perceived character. For example, `q̣̇` is a normal\n\t* letter `q` with two \"combining marks\": upper dot (`Ux0307`) and lower dot (`Ux0323`). For most actions, i.e. extending\n\t* selection by one position, it is correct to include both \"base character\" and all of it's \"combining marks\". That is\n\t* why `'character'` value is most natural and common method of modifying selection.\n\t* * `'codePoint'` - moves selection by one unicode code point. In contrary to, `'character'` unit, this will insert\n\t* selection between \"base character\" and \"combining mark\", because \"combining marks\" have their own unicode code points.\n\t* However, for technical reasons, unicode code points with values above `UxFFFF` are represented in native `String` by\n\t* two characters, called \"surrogate pairs\". Halves of \"surrogate pairs\" have a meaning only when placed next to each other.\n\t* For example `𨭎` is represented in `String` by `\\uD862\\uDF4E`. Both `\\uD862` and `\\uDF4E` do not have any meaning\n\t* outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection\n\t* extension will include whole \"surrogate pair\".\n\t* * `'word'` - moves selection by a whole word.\n\t*\n\t* **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n\t*\n\t* @fires modifySelection\n\t* @param selection The selection to modify.\n\t* @param options.direction The direction in which the selection should be modified.\n\t* @param options.unit The unit by which selection should be modified.\n\t* @param options.treatEmojiAsSingleUnit Whether multi-characer emoji sequences should be handled as single unit.\n\t*/\n\tmodifySelection(selection, options) {\n\t\tmodifySelection(this, selection, options);\n\t}\n\t/**\n\t* Gets a clone of the selected content.\n\t*\n\t* For example, for the following selection:\n\t*\n\t* ```html\n\t* <paragraph>x</paragraph>\n\t* <blockQuote>\n\t* \t<paragraph>y</paragraph>\n\t* \t<heading1>fir[st</heading1>\n\t* </blockQuote>\n\t* <paragraph>se]cond</paragraph>\n\t* <paragraph>z</paragraph>\n\t* ```\n\t*\n\t* It will return a document fragment with such a content:\n\t*\n\t* ```html\n\t* <blockQuote>\n\t* \t<heading1>st</heading1>\n\t* </blockQuote>\n\t* <paragraph>se</paragraph>\n\t* ```\n\t*\n\t* @fires getSelectedContent\n\t* @param selection The selection of which content will be returned.\n\t*/\n\tgetSelectedContent(selection) {\n\t\treturn getSelectedContent(this, selection);\n\t}\n\t/**\n\t* Checks whether given `subject` has any meaningful content.\n\t*\n\t* Meaningful content is:\n\t*\n\t* * any text node (`options.ignoreWhitespaces` allows controlling whether this text node must also contain\n\t* any non-whitespace characters),\n\t* * or any {@link module:engine/model/schema~ModelSchema#isContent content element},\n\t* * or any {@link module:engine/model/markercollection~Marker marker} which\n\t* {@link module:engine/model/markercollection~Marker#_affectsData affects data}.\n\t*\n\t* This means that a range containing an empty `<paragraph></paragraph>` is not considered to have a meaningful content.\n\t* However, a range containing an `<imageBlock></imageBlock>` (which would normally be marked in the schema as an object element)\n\t* is considered non-empty.\n\t*\n\t* @param subject Subject to check if includes meaningful content. Could be a model range, an element, a document fragment, or a\n\t* selection.\n\t* @param options.ignoreWhitespaces Whether text node with whitespaces only should be considered empty.\n\t* @param options.ignoreMarkers Whether markers should be ignored.\n\t*/\n\thasContent(subject, options = {}) {\n\t\tlet ranges;\n\t\tif (subject.is(\"selection\")) ranges = Array.from(subject.getRanges());\n\t\telse if (subject.is(\"range\")) ranges = [subject];\n\t\telse ranges = [ModelRange._createIn(subject)];\n\t\tfor (const range of ranges) if (this._rangeHasContent(range, options)) return true;\n\t\treturn false;\n\t}\n\t/**\n\t* Checks whether given range has any meaningful content.\n\t*\n\t* Helper method for {@link #hasContent}.\n\t*/\n\t_rangeHasContent(range, options) {\n\t\tif (range.isCollapsed) return false;\n\t\tconst { ignoreWhitespaces = false, ignoreMarkers = false } = options;\n\t\tif (!ignoreMarkers) {\n\t\t\tfor (const intersectingMarker of this.markers.getMarkersIntersectingRange(range)) if (intersectingMarker.affectsData) return true;\n\t\t}\n\t\tfor (const item of range.getItems()) if (this.schema.isContent(item)) if (item.is(\"$textProxy\")) {\n\t\t\tif (!ignoreWhitespaces) return true;\n\t\t\telse if (item.data.search(/\\S/) !== -1) return true;\n\t\t} else return true;\n\t\treturn false;\n\t}\n\t/**\n\t* Check whether given selectable is at a place in the model where it can be edited (returns `true`) or not (returns `false`).\n\t*\n\t* Should be used instead of {@link module:core/editor/editor~Editor#isReadOnly} to check whether a user action can happen at\n\t* given selectable. It may be decorated and used differently in different environment (e.g. multi-root editor can disable\n\t* a particular root).\n\t*\n\t* This method is decorated. Although this method accepts any parameter of `Selectable` type, the\n\t* {@link ~Model#event:canEditAt `canEditAt` event} is fired with `selectable` normalized to an instance of\n\t* {@link module:engine/model/selection~ModelSelection} or {@link module:engine/model/documentselection~ModelDocumentSelection}\n\t*\n\t* @fires canEditAt\n\t*/\n\tcanEditAt(selectable) {\n\t\tconst selection = normalizeSelectable(selectable);\n\t\treturn this.fire(\"canEditAt\", [selection]);\n\t}\n\t/**\n\t* Creates a position from the given root and path in that root.\n\t*\n\t* Note: This method is also available as\n\t* {@link module:engine/model/writer~ModelWriter#createPositionFromPath `Writer#createPositionFromPath()`}.\n\t*\n\t* @param root Root of the position.\n\t* @param path Position path. See {@link module:engine/model/position~ModelPosition#path}.\n\t* @param stickiness Position stickiness. See {@link module:engine/model/position~ModelPositionStickiness}.\n\t*/\n\tcreatePositionFromPath(root, path, stickiness) {\n\t\treturn new ModelPosition(root, path, stickiness);\n\t}\n\t/**\n\t* Creates position at the given location. The location can be specified as:\n\t*\n\t* * a {@link module:engine/model/position~ModelPosition position},\n\t* * a parent element and offset in that element,\n\t* * a parent element and `'end'` (the position will be set at the end of that element),\n\t* * a {@link module:engine/model/item~ModelItem model item} and `'before'` or `'after'`\n\t* (the position will be set before or after the given model item).\n\t*\n\t* This method is a shortcut to other factory methods such as:\n\t*\n\t* * {@link module:engine/model/model~Model#createPositionBefore `createPositionBefore()`},\n\t* * {@link module:engine/model/model~Model#createPositionAfter `createPositionAfter()`}.\n\t*\n\t* Note: This method is also available as\n\t* {@link module:engine/model/writer~ModelWriter#createPositionAt `Writer#createPositionAt()`},\n\t*\n\t* @param itemOrPosition\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~ModelItem model item}.\n\t*/\n\tcreatePositionAt(itemOrPosition, offset) {\n\t\treturn ModelPosition._createAt(itemOrPosition, offset);\n\t}\n\t/**\n\t* Creates a new position after the given {@link module:engine/model/item~ModelItem model item}.\n\t*\n\t* Note: This method is also available as\n\t* {@link module:engine/model/writer~ModelWriter#createPositionAfter `Writer#createPositionAfter()`}.\n\t*\n\t* @param item Item after which the position should be placed.\n\t*/\n\tcreatePositionAfter(item) {\n\t\treturn ModelPosition._createAfter(item);\n\t}\n\t/**\n\t* Creates a new position before the given {@link module:engine/model/item~ModelItem model item}.\n\t*\n\t* Note: This method is also available as\n\t* {@link module:engine/model/writer~ModelWriter#createPositionBefore `Writer#createPositionBefore()`}.\n\t*\n\t* @param item Item before which the position should be placed.\n\t*/\n\tcreatePositionBefore(item) {\n\t\treturn ModelPosition._createBefore(item);\n\t}\n\t/**\n\t* Creates a range spanning from the `start` position to the `end` position.\n\t*\n\t* Note: This method is also available as\n\t* {@link module:engine/model/writer~ModelWriter#createRange `Writer#createRange()`}:\n\t*\n\t* ```ts\n\t* model.change( writer => {\n\t* \tconst range = writer.createRange( start, end );\n\t* } );\n\t* ```\n\t*\n\t* @param start Start position.\n\t* @param end End position. If not set, the range will be collapsed to the `start` position.\n\t*/\n\tcreateRange(start, end) {\n\t\treturn new ModelRange(start, end);\n\t}\n\t/**\n\t* Creates a range inside the given element which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* Note: This method is also available as\n\t* {@link module:engine/model/writer~ModelWriter#createRangeIn `Writer#createRangeIn()`}:\n\t*\n\t* ```ts\n\t* model.change( writer => {\n\t* \tconst range = writer.createRangeIn( paragraph );\n\t* } );\n\t* ```\n\t*\n\t* @param element Element which is a parent for the range.\n\t*/\n\tcreateRangeIn(element) {\n\t\treturn ModelRange._createIn(element);\n\t}\n\t/**\n\t* Creates a range that starts before the given {@link module:engine/model/item~ModelItem model item} and ends after it.\n\t*\n\t* Note: This method is also available on `writer` instance as\n\t* {@link module:engine/model/writer~ModelWriter#createRangeOn `Writer.createRangeOn()`}:\n\t*\n\t* ```ts\n\t* model.change( writer => {\n\t* \tconst range = writer.createRangeOn( paragraph );\n\t* } );\n\t* ```\n\t*\n\t* @param item\n\t*/\n\tcreateRangeOn(item) {\n\t\treturn ModelRange._createOn(item);\n\t}\n\tcreateSelection(...args) {\n\t\treturn new ModelSelection(...args);\n\t}\n\t/**\n\t* Creates a {@link module:engine/model/batch~Batch} instance.\n\t*\n\t* **Note:** In most cases creating a batch instance is not necessary as they are created when using:\n\t*\n\t* * {@link #change `change()`},\n\t* * {@link #enqueueChange `enqueueChange()`}.\n\t*\n\t* @param type {@link module:engine/model/batch~Batch#constructor The type} of the batch.\n\t*/\n\tcreateBatch(type) {\n\t\treturn new Batch(type);\n\t}\n\t/**\n\t* Creates an operation instance from a JSON object (parsed JSON string).\n\t*\n\t* This is an alias for {@link module:engine/model/operation/operationfactory~OperationFactory.fromJSON `OperationFactory.fromJSON()`}.\n\t*\n\t* @param json Deserialized JSON object.\n\t*/\n\tcreateOperationFromJSON(json) {\n\t\treturn OperationFactory.fromJSON(json, this.document);\n\t}\n\t/**\n\t* Removes all events listeners set by model instance and destroys {@link module:engine/model/document~ModelDocument}.\n\t*/\n\tdestroy() {\n\t\tthis.document.destroy();\n\t\tthis.markers.destroy();\n\t\tthis.stopListening();\n\t}\n\t/**\n\t* Common part of {@link module:engine/model/model~Model#change} and {@link module:engine/model/model~Model#enqueueChange}\n\t* which calls callbacks and returns array of values returned by these callbacks.\n\t*/\n\t_runPendingChanges() {\n\t\tconst ret = [];\n\t\tthis.fire(\"_beforeChanges\");\n\t\ttry {\n\t\t\twhile (this._pendingChanges.length) {\n\t\t\t\tconst currentBatch = this._pendingChanges[0].batch;\n\t\t\t\tthis._currentWriter = new ModelWriter(this, currentBatch);\n\t\t\t\tconst callbackReturnValue = this._pendingChanges[0].callback(this._currentWriter);\n\t\t\t\tret.push(callbackReturnValue);\n\t\t\t\tthis.document._handleChangeBlock(this._currentWriter);\n\t\t\t\tthis._pendingChanges.shift();\n\t\t\t\tthis._currentWriter = null;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._pendingChanges.length = 0;\n\t\t\tthis._currentWriter = null;\n\t\t\tthis.fire(\"_afterChanges\");\n\t\t}\n\t\treturn ret;\n\t}\n};\n/**\n* Normalizes a selectable to a Selection or ModelDocumentSelection.\n*/\nfunction normalizeSelectable(selectable, placeOrOffset) {\n\tif (!selectable) return;\n\tif (selectable instanceof ModelSelection || selectable instanceof ModelDocumentSelection) return selectable;\n\tif (selectable instanceof ModelNode) if (placeOrOffset || placeOrOffset === 0) return new ModelSelection(selectable, placeOrOffset);\n\telse if (selectable.is(\"rootElement\")) return new ModelSelection(selectable, \"in\");\n\telse return new ModelSelection(selectable, \"on\");\n\treturn new ModelSelection(selectable);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/clickobserver\n*/\n/**\n* {@link module:engine/view/document~ViewDocument#event:click Click} event observer.\n*\n* Note that this observer is not available by default. To make it available it needs to be added to\n* {@link module:engine/view/view~EditingView view controller} by a {@link module:engine/view/view~EditingView#addObserver} method.\n*/\nvar ClickObserver = class extends DomEventObserver {\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = \"click\";\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvent) {\n\t\tthis.fire(domEvent.type, domEvent);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/mouseobserver\n*/\n/**\n* Mouse events observer.\n*\n* Note that this observer is not available by default. To make it available it needs to be added to\n* {@link module:engine/view/view~EditingView} by {@link module:engine/view/view~EditingView#addObserver} method.\n*/\nvar MouseObserver = class extends DomEventObserver {\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = [\n\t\t\"mousedown\",\n\t\t\"mouseup\",\n\t\t\"mouseover\",\n\t\t\"mouseout\"\n\t];\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvent) {\n\t\tthis.fire(domEvent.type, domEvent);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/touchobserver\n*/\n/**\n* Touch events observer.\n*\n* Note that this observer is not available by default. To make it available it needs to be added to\n* {@link module:engine/view/view~EditingView} by {@link module:engine/view/view~EditingView#addObserver} method.\n*/\nvar TouchObserver = class extends DomEventObserver {\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = [\n\t\t\"touchstart\",\n\t\t\"touchend\",\n\t\t\"touchmove\"\n\t];\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvent) {\n\t\tthis.fire(domEvent.type, domEvent);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/observer/pointerobserver\n*/\n/**\n* Pointer events observer.\n*\n* Note that this observer is not available by default. To make it available it needs to be added to\n* {@link module:engine/view/view~EditingView} by {@link module:engine/view/view~EditingView#addObserver} method.\n*/\nvar PointerObserver = class extends DomEventObserver {\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = [\n\t\t\"pointerdown\",\n\t\t\"pointerup\",\n\t\t\"pointermove\"\n\t];\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvent) {\n\t\tthis.fire(domEvent.type, domEvent);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/upcastwriter\n*/\n/**\n* View upcast writer. It provides a set of methods used to manipulate non-semantic view trees.\n*\n* It should be used only while working on a non-semantic view\n* (e.g. a view created from HTML string on paste).\n* To manipulate a view which was or is being downcasted from the the model use the\n* {@link module:engine/view/downcastwriter~ViewDowncastWriter downcast writer}.\n*\n* Read more about changing the view in the {@glink framework/architecture/editing-engine#changing-the-view Changing the view}\n* section of the {@glink framework/architecture/editing-engine Editing engine architecture} guide.\n*\n* Unlike `ViewDowncastWriter`, which is available in the {@link module:engine/view/view~EditingView#change `View#change()`} block,\n* `ViewUpcastWriter` can be created wherever you need it:\n*\n* ```ts\n* const writer = new ViewUpcastWriter( viewDocument );\n* const text = writer.createText( 'foo!' );\n*\n* writer.appendChild( text, someViewElement );\n* ```\n*/\nvar ViewUpcastWriter = class {\n\t/**\n\t* The view document instance in which this upcast writer operates.\n\t*/\n\tdocument;\n\t/**\n\t* @param document The view document instance in which this upcast writer operates.\n\t*/\n\tconstructor(document) {\n\t\tthis.document = document;\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/documentfragment~ViewDocumentFragment} instance.\n\t*\n\t* @param children A list of nodes to be inserted into the created document fragment.\n\t* @returns The created document fragment.\n\t*/\n\tcreateDocumentFragment(children) {\n\t\treturn new ViewDocumentFragment(this.document, children);\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/element~ViewElement} instance.\n\t*\n\t* Attributes can be passed in various formats:\n\t*\n\t* ```ts\n\t* upcastWriter.createElement( 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t* upcastWriter.createElement( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t* upcastWriter.createElement( 'div', mapOfAttributes ); // map\n\t* ```\n\t*\n\t* @param name Node name.\n\t* @param attrs Collection of attributes.\n\t* @param children A list of nodes to be inserted into created element.\n\t* @returns Created element.\n\t*/\n\tcreateElement(name, attrs, children) {\n\t\treturn new ViewElement(this.document, name, attrs, children);\n\t}\n\t/**\n\t* Creates a new {@link module:engine/view/text~ViewText} instance.\n\t*\n\t* @param data The text's data.\n\t* @returns The created text node.\n\t*/\n\tcreateText(data) {\n\t\treturn new ViewText(this.document, data);\n\t}\n\t/**\n\t* Clones the provided element.\n\t*\n\t* @see module:engine/view/element~ViewElement#_clone\n\t* @param element Element to be cloned.\n\t* @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t* element will be cloned without any children.\n\t* @returns Clone of this element.\n\t*/\n\tclone(element, deep = false) {\n\t\treturn element._clone(deep);\n\t}\n\t/**\n\t* Appends a child node or a list of child nodes at the end of this node\n\t* and sets the parent of these nodes to this element.\n\t*\n\t* @see module:engine/view/element~ViewElement#_appendChild\n\t* @param items Items to be inserted.\n\t* @param element Element to which items will be appended.\n\t* @returns Number of appended nodes.\n\t*/\n\tappendChild(items, element) {\n\t\treturn element._appendChild(items);\n\t}\n\t/**\n\t* Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t* this element.\n\t*\n\t* @see module:engine/view/element~ViewElement#_insertChild\n\t* @param index Offset at which nodes should be inserted.\n\t* @param items Items to be inserted.\n\t* @param element Element to which items will be inserted.\n\t* @returns Number of inserted nodes.\n\t*/\n\tinsertChild(index, items, element) {\n\t\treturn element._insertChild(index, items);\n\t}\n\t/**\n\t* Removes the given number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t*\n\t* @see module:engine/view/element~ViewElement#_removeChildren\n\t* @param index Offset from which nodes will be removed.\n\t* @param howMany Number of nodes to remove.\n\t* @param element Element which children will be removed.\n\t* @returns The array containing removed nodes.\n\t*/\n\tremoveChildren(index, howMany, element) {\n\t\treturn element._removeChildren(index, howMany);\n\t}\n\t/**\n\t* Removes given element from the view structure. Will not have effect on detached elements.\n\t*\n\t* @param element Element which will be removed.\n\t* @returns The array containing removed nodes.\n\t*/\n\tremove(element) {\n\t\tconst parent = element.parent;\n\t\tif (parent) return this.removeChildren(parent.getChildIndex(element), 1, parent);\n\t\treturn [];\n\t}\n\t/**\n\t* Replaces given element with the new one in the view structure. Will not have effect on detached elements.\n\t*\n\t* @param oldElement Element which will be replaced.\n\t* @param newElement Element which will be inserted in the place of the old element.\n\t* @returns Whether old element was successfully replaced.\n\t*/\n\treplace(oldElement, newElement) {\n\t\tconst parent = oldElement.parent;\n\t\tif (parent) {\n\t\t\tconst index = parent.getChildIndex(oldElement);\n\t\t\tthis.removeChildren(index, 1, parent);\n\t\t\tthis.insertChild(index, newElement, parent);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\t/**\n\t* Removes given element from view structure and places its children in its position.\n\t* It does nothing if element has no parent.\n\t*\n\t* @param element Element to unwrap.\n\t*/\n\tunwrapElement(element) {\n\t\tconst parent = element.parent;\n\t\tif (parent) {\n\t\t\tconst index = parent.getChildIndex(element);\n\t\t\tthis.remove(element);\n\t\t\tthis.insertChild(index, element.getChildren(), parent);\n\t\t}\n\t}\n\t/**\n\t* Renames element by creating a copy of a given element but with its name changed and then moving contents of the\n\t* old element to the new one.\n\t*\n\t* Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t*\n\t* @param newName New element name.\n\t* @param element Element to be renamed.\n\t* @returns New element or null if the old element was not replaced (happens for detached elements).\n\t*/\n\trename(newName, element) {\n\t\tconst newElement = new ViewElement(this.document, newName, element.getAttributes(), element.getChildren());\n\t\treturn this.replace(element, newElement) ? newElement : null;\n\t}\n\t/**\n\t* Adds or overwrites element's attribute with a specified key and value.\n\t*\n\t* ```ts\n\t* writer.setAttribute( 'href', 'http://ckeditor.com', linkElement );\n\t* ```\n\t*\n\t* @see module:engine/view/element~ViewElement#_setAttribute\n\t* @param key Attribute key.\n\t* @param value Attribute value.\n\t* @param element Element for which attribute will be set.\n\t*/\n\tsetAttribute(key, value, element) {\n\t\telement._setAttribute(key, value);\n\t}\n\t/**\n\t* Removes attribute from the element.\n\t*\n\t* ```ts\n\t* writer.removeAttribute( 'href', linkElement );\n\t* ```\n\t*\n\t* @see module:engine/view/element~ViewElement#_removeAttribute\n\t* @param key Attribute key.\n\t* @param element Element from which attribute will be removed.\n\t*/\n\tremoveAttribute(key, element) {\n\t\telement._removeAttribute(key);\n\t}\n\t/**\n\t* Adds specified class to the element.\n\t*\n\t* ```ts\n\t* writer.addClass( 'foo', linkElement );\n\t* writer.addClass( [ 'foo', 'bar' ], linkElement );\n\t* ```\n\t*\n\t* @see module:engine/view/element~ViewElement#_addClass\n\t* @param className Single class name or array of class names which will be added.\n\t* @param element Element for which class will be added.\n\t*/\n\taddClass(className, element) {\n\t\telement._addClass(className);\n\t}\n\t/**\n\t* Removes specified class from the element.\n\t*\n\t* ```ts\n\t* writer.removeClass( 'foo', linkElement );\n\t* writer.removeClass( [ 'foo', 'bar' ], linkElement );\n\t* ```\n\t*\n\t* @see module:engine/view/element~ViewElement#_removeClass\n\t* @param className Single class name or array of class names which will be removed.\n\t* @param element Element from which class will be removed.\n\t*/\n\tremoveClass(className, element) {\n\t\telement._removeClass(className);\n\t}\n\tsetStyle(property, valueOrElement, element) {\n\t\tif (isPlainObject(property) && element === void 0) valueOrElement._setStyle(property);\n\t\telse element._setStyle(property, valueOrElement);\n\t}\n\t/**\n\t* Removes specified style from the element.\n\t*\n\t* ```ts\n\t* writer.removeStyle( 'color', element ); // Removes 'color' style.\n\t* writer.removeStyle( [ 'color', 'border-top' ], element ); // Removes both 'color' and 'border-top' styles.\n\t* ```\n\t*\n\t* **Note**: This method can work with normalized style names if\n\t* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t* See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t*\n\t* @see module:engine/view/element~ViewElement#_removeStyle\n\t* @param property Style property name or names to be removed.\n\t* @param element Element from which style will be removed.\n\t*/\n\tremoveStyle(property, element) {\n\t\telement._removeStyle(property);\n\t}\n\t/**\n\t* Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t* so they can be used to add special data to elements.\n\t*\n\t* @see module:engine/view/element~ViewElement#_setCustomProperty\n\t* @param key Custom property name/key.\n\t* @param value Custom property value to be stored.\n\t* @param element Element for which custom property will be set.\n\t*/\n\tsetCustomProperty(key, value, element) {\n\t\telement._setCustomProperty(key, value);\n\t}\n\t/**\n\t* Removes a custom property stored under the given key.\n\t*\n\t* @see module:engine/view/element~ViewElement#_removeCustomProperty\n\t* @param key Name/key of the custom property to be removed.\n\t* @param element Element from which the custom property will be removed.\n\t* @returns Returns true if property was removed.\n\t*/\n\tremoveCustomProperty(key, element) {\n\t\treturn element._removeCustomProperty(key);\n\t}\n\t/**\n\t* Creates position at the given location. The location can be specified as:\n\t*\n\t* * a {@link module:engine/view/position~ViewPosition position},\n\t* * parent element and offset (offset defaults to `0`),\n\t* * parent element and `'end'` (sets position at the end of that element),\n\t* * {@link module:engine/view/item~ViewItem view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t*\n\t* This method is a shortcut to other constructors such as:\n\t*\n\t* * {@link #createPositionBefore},\n\t* * {@link #createPositionAfter},\n\t*\n\t* @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~ViewItem view item}.\n\t*/\n\tcreatePositionAt(itemOrPosition, offset) {\n\t\treturn ViewPosition._createAt(itemOrPosition, offset);\n\t}\n\t/**\n\t* Creates a new position after given view item.\n\t*\n\t* @param item View item after which the position should be located.\n\t*/\n\tcreatePositionAfter(item) {\n\t\treturn ViewPosition._createAfter(item);\n\t}\n\t/**\n\t* Creates a new position before given view item.\n\t*\n\t* @param item View item before which the position should be located.\n\t*/\n\tcreatePositionBefore(item) {\n\t\treturn ViewPosition._createBefore(item);\n\t}\n\t/**\n\t* Creates a range spanning from `start` position to `end` position.\n\t*\n\t* **Note:** This factory method creates it's own {@link module:engine/view/position~ViewPosition} instances basing on passed values.\n\t*\n\t* @param start Start position.\n\t* @param end End position. If not set, range will be collapsed at `start` position.\n\t*/\n\tcreateRange(start, end) {\n\t\treturn new ViewRange(start, end);\n\t}\n\t/**\n\t* Creates a range that starts before given {@link module:engine/view/item~ViewItem view item} and ends after it.\n\t*/\n\tcreateRangeOn(item) {\n\t\treturn ViewRange._createOn(item);\n\t}\n\t/**\n\t* Creates a range inside an {@link module:engine/view/element~ViewElement element} which starts before the first child of\n\t* that element and ends after the last child of that element.\n\t*\n\t* @param element Element which is a parent for the range.\n\t*/\n\tcreateRangeIn(element) {\n\t\treturn ViewRange._createIn(element);\n\t}\n\tcreateSelection(...args) {\n\t\treturn new ViewSelection(...args);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\nconst HEX_COLOR_REGEXP = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;\nconst RGB_COLOR_REGEXP = /^rgb\\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}[0-9]{1,3}[ %]?\\)$/i;\nconst RGBA_COLOR_REGEXP = /^rgba\\([ ]?([0-9]{1,3}[ %]?,[ ]?){3}(1|[0-9]+%|[0]?\\.?[0-9]+)\\)$/i;\nconst HSL_COLOR_REGEXP = /^hsl\\([ ]?([0-9]{1,3}[ %]?[,]?[ ]*){3}(1|[0-9]+%|[0]?\\.?[0-9]+)?\\)$/i;\nconst HSLA_COLOR_REGEXP = /^hsla\\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}(1|[0-9]+%|[0]?\\.?[0-9]+)\\)$/i;\nconst CSS_SHORTHAND_VALUE_REGEXP = /\\w+\\((?:[^()]|\\([^()]*\\))*\\)|\\S+/gi;\nconst COLOR_NAMES = /* @__PURE__ */ new Set([\n\t\"black\",\n\t\"silver\",\n\t\"gray\",\n\t\"white\",\n\t\"maroon\",\n\t\"red\",\n\t\"purple\",\n\t\"fuchsia\",\n\t\"green\",\n\t\"lime\",\n\t\"olive\",\n\t\"yellow\",\n\t\"navy\",\n\t\"blue\",\n\t\"teal\",\n\t\"aqua\",\n\t\"orange\",\n\t\"aliceblue\",\n\t\"antiquewhite\",\n\t\"aquamarine\",\n\t\"azure\",\n\t\"beige\",\n\t\"bisque\",\n\t\"blanchedalmond\",\n\t\"blueviolet\",\n\t\"brown\",\n\t\"burlywood\",\n\t\"cadetblue\",\n\t\"chartreuse\",\n\t\"chocolate\",\n\t\"coral\",\n\t\"cornflowerblue\",\n\t\"cornsilk\",\n\t\"crimson\",\n\t\"cyan\",\n\t\"darkblue\",\n\t\"darkcyan\",\n\t\"darkgoldenrod\",\n\t\"darkgray\",\n\t\"darkgreen\",\n\t\"darkgrey\",\n\t\"darkkhaki\",\n\t\"darkmagenta\",\n\t\"darkolivegreen\",\n\t\"darkorange\",\n\t\"darkorchid\",\n\t\"darkred\",\n\t\"darksalmon\",\n\t\"darkseagreen\",\n\t\"darkslateblue\",\n\t\"darkslategray\",\n\t\"darkslategrey\",\n\t\"darkturquoise\",\n\t\"darkviolet\",\n\t\"deeppink\",\n\t\"deepskyblue\",\n\t\"dimgray\",\n\t\"dimgrey\",\n\t\"dodgerblue\",\n\t\"firebrick\",\n\t\"floralwhite\",\n\t\"forestgreen\",\n\t\"gainsboro\",\n\t\"ghostwhite\",\n\t\"gold\",\n\t\"goldenrod\",\n\t\"greenyellow\",\n\t\"grey\",\n\t\"honeydew\",\n\t\"hotpink\",\n\t\"indianred\",\n\t\"indigo\",\n\t\"ivory\",\n\t\"khaki\",\n\t\"lavender\",\n\t\"lavenderblush\",\n\t\"lawngreen\",\n\t\"lemonchiffon\",\n\t\"lightblue\",\n\t\"lightcoral\",\n\t\"lightcyan\",\n\t\"lightgoldenrodyellow\",\n\t\"lightgray\",\n\t\"lightgreen\",\n\t\"lightgrey\",\n\t\"lightpink\",\n\t\"lightsalmon\",\n\t\"lightseagreen\",\n\t\"lightskyblue\",\n\t\"lightslategray\",\n\t\"lightslategrey\",\n\t\"lightsteelblue\",\n\t\"lightyellow\",\n\t\"limegreen\",\n\t\"linen\",\n\t\"magenta\",\n\t\"mediumaquamarine\",\n\t\"mediumblue\",\n\t\"mediumorchid\",\n\t\"mediumpurple\",\n\t\"mediumseagreen\",\n\t\"mediumslateblue\",\n\t\"mediumspringgreen\",\n\t\"mediumturquoise\",\n\t\"mediumvioletred\",\n\t\"midnightblue\",\n\t\"mintcream\",\n\t\"mistyrose\",\n\t\"moccasin\",\n\t\"navajowhite\",\n\t\"oldlace\",\n\t\"olivedrab\",\n\t\"orangered\",\n\t\"orchid\",\n\t\"palegoldenrod\",\n\t\"palegreen\",\n\t\"paleturquoise\",\n\t\"palevioletred\",\n\t\"papayawhip\",\n\t\"peachpuff\",\n\t\"peru\",\n\t\"pink\",\n\t\"plum\",\n\t\"powderblue\",\n\t\"rosybrown\",\n\t\"royalblue\",\n\t\"saddlebrown\",\n\t\"salmon\",\n\t\"sandybrown\",\n\t\"seagreen\",\n\t\"seashell\",\n\t\"sienna\",\n\t\"skyblue\",\n\t\"slateblue\",\n\t\"slategray\",\n\t\"slategrey\",\n\t\"snow\",\n\t\"springgreen\",\n\t\"steelblue\",\n\t\"tan\",\n\t\"thistle\",\n\t\"tomato\",\n\t\"turquoise\",\n\t\"violet\",\n\t\"wheat\",\n\t\"whitesmoke\",\n\t\"yellowgreen\",\n\t\"activeborder\",\n\t\"activecaption\",\n\t\"appworkspace\",\n\t\"background\",\n\t\"buttonface\",\n\t\"buttonhighlight\",\n\t\"buttonshadow\",\n\t\"buttontext\",\n\t\"captiontext\",\n\t\"graytext\",\n\t\"highlight\",\n\t\"highlighttext\",\n\t\"inactiveborder\",\n\t\"inactivecaption\",\n\t\"inactivecaptiontext\",\n\t\"infobackground\",\n\t\"infotext\",\n\t\"menu\",\n\t\"menutext\",\n\t\"scrollbar\",\n\t\"threeddarkshadow\",\n\t\"threedface\",\n\t\"threedhighlight\",\n\t\"threedlightshadow\",\n\t\"threedshadow\",\n\t\"window\",\n\t\"windowframe\",\n\t\"windowtext\",\n\t\"rebeccapurple\",\n\t\"currentcolor\",\n\t\"transparent\"\n]);\n/**\n* Checks if string contains [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) CSS value.\n*\n* ```ts\n* isColorStyleValue( '#f00' );\t\t\t\t\t\t// true\n* isColorStyleValue( '#AA00BB33' );\t\t\t\t// true\n* isColorStyleValue( 'rgb(0, 0, 250)' );\t\t\t// true\n* isColorStyleValue( 'hsla(240, 100%, 50%, .7)' );\t// true\n* isColorStyleValue( 'deepskyblue' );\t\t\t\t// true\n* ```\n*\n* **Note**: It does not support CSS Level 4 whitespace syntax, system colors and radius values for HSL colors.\n*/\nfunction isColorStyleValue(string) {\n\tif (string.startsWith(\"#\")) return HEX_COLOR_REGEXP.test(string);\n\tif (string.startsWith(\"rgb\")) return RGB_COLOR_REGEXP.test(string) || RGBA_COLOR_REGEXP.test(string);\n\tif (string.startsWith(\"hsl\")) return HSL_COLOR_REGEXP.test(string) || HSLA_COLOR_REGEXP.test(string);\n\treturn COLOR_NAMES.has(string.toLowerCase());\n}\nconst lineStyleValues = [\n\t\"none\",\n\t\"hidden\",\n\t\"dotted\",\n\t\"dashed\",\n\t\"solid\",\n\t\"double\",\n\t\"groove\",\n\t\"ridge\",\n\t\"inset\",\n\t\"outset\"\n];\n/**\n* Checks if string contains [line style](https://developer.mozilla.org/en-US/docs/Web/CSS/border-style) CSS value.\n*/\nfunction isLineStyleValue(string) {\n\treturn lineStyleValues.includes(string);\n}\nconst lengthRegExp = /^([+-]?[0-9]*([.][0-9]+)?(px|cm|mm|in|pc|pt|ch|em|ex|rem|vh|vw|vmin|vmax)|0)$/;\n/**\n* Checks if string contains [length](https://developer.mozilla.org/en-US/docs/Web/CSS/length) CSS value.\n*/\nfunction isLengthStyleValue(string) {\n\treturn lengthRegExp.test(string);\n}\nconst PERCENTAGE_VALUE_REGEXP = /^[+-]?[0-9]*([.][0-9]+)?%$/;\n/**\n* Checks if string contains [percentage](https://developer.mozilla.org/en-US/docs/Web/CSS/percentage) CSS value.\n*/\nfunction isPercentageStyleValue(string) {\n\treturn PERCENTAGE_VALUE_REGEXP.test(string);\n}\nconst sizeValues = [\n\t\"auto\",\n\t\"cover\",\n\t\"contain\"\n];\n/**\n* Checks if a string is a valid CSS `background-size` value token.\n*/\nfunction isSizeStyleValue(value) {\n\treturn sizeValues.includes(value) || isLengthStyleValue(value) || isPercentageStyleValue(value);\n}\nconst repeatValues = [\n\t\"repeat-x\",\n\t\"repeat-y\",\n\t\"repeat\",\n\t\"space\",\n\t\"round\",\n\t\"no-repeat\"\n];\n/**\n* Checks if string contains [background repeat](https://developer.mozilla.org/en-US/docs/Web/CSS/background-repeat) CSS value.\n*/\nfunction isRepeatStyleValue(string) {\n\treturn repeatValues.includes(string);\n}\nconst positionValues = [\n\t\"center\",\n\t\"top\",\n\t\"bottom\",\n\t\"left\",\n\t\"right\"\n];\n/**\n* Checks if string contains [background position](https://developer.mozilla.org/en-US/docs/Web/CSS/background-position) CSS value.\n*/\nfunction isPositionStyleValue(string) {\n\treturn positionValues.includes(string);\n}\nconst attachmentValues = [\n\t\"fixed\",\n\t\"scroll\",\n\t\"local\"\n];\n/**\n* Checks if string contains [background attachment](https://developer.mozilla.org/en-US/docs/Web/CSS/background-attachment) CSS value.\n*/\nfunction isAttachmentStyleValue(string) {\n\treturn attachmentValues.includes(string);\n}\nconst originValues = [\n\t\"border-box\",\n\t\"padding-box\",\n\t\"content-box\"\n];\n/**\n* Checks if string contains [background origin](https://developer.mozilla.org/en-US/docs/Web/CSS/background-origin) CSS value.\n*/\nfunction isOriginStyleValue(string) {\n\treturn originValues.includes(string);\n}\nconst clipValues = [\n\t\"border-box\",\n\t\"padding-box\",\n\t\"content-box\",\n\t\"text\"\n];\n/**\n* Checks if string contains [background clip](https://developer.mozilla.org/en-US/docs/Web/CSS/background-clip) CSS value.\n*/\nfunction isClipStyleValue(string) {\n\treturn clipValues.includes(string);\n}\nconst urlRegExp = /^url\\(/;\n/**\n* Checks if string contains [URL](https://developer.mozilla.org/en-US/docs/Web/CSS/url) CSS value.\n*/\nfunction isURLStyleValue(string) {\n\treturn urlRegExp.test(string);\n}\n/**\n* Parses box sides as individual values.\n*/\nfunction getBoxSidesStyleValues(value = \"\") {\n\tif (value === \"\") return {\n\t\ttop: void 0,\n\t\tright: void 0,\n\t\tbottom: void 0,\n\t\tleft: void 0\n\t};\n\tconst values = getShorthandStylesValues(value);\n\tconst top = values[0];\n\tconst bottom = values[2] || top;\n\tconst right = values[1] || top;\n\treturn {\n\t\ttop,\n\t\tbottom,\n\t\tright,\n\t\tleft: values[3] || right\n\t};\n}\n/**\n* Default reducer for CSS properties that concerns edges of a box\n* [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) notations:\n*\n* ```ts\n* stylesProcessor.setReducer( 'padding', getBoxSidesStyleValueReducer( 'padding' ) );\n* ```\n*/\nfunction getBoxSidesStyleValueReducer(styleShorthand) {\n\treturn (value) => {\n\t\tconst { top, right, bottom, left } = value;\n\t\tconst reduced = [];\n\t\tif (![\n\t\t\ttop,\n\t\t\tright,\n\t\t\tleft,\n\t\t\tbottom\n\t\t].every((value) => !!value)) {\n\t\t\tif (top) reduced.push([styleShorthand + \"-top\", top]);\n\t\t\tif (right) reduced.push([styleShorthand + \"-right\", right]);\n\t\t\tif (bottom) reduced.push([styleShorthand + \"-bottom\", bottom]);\n\t\t\tif (left) reduced.push([styleShorthand + \"-left\", left]);\n\t\t} else reduced.push([styleShorthand, getBoxSidesStyleShorthandValue(value)]);\n\t\treturn reduced;\n\t};\n}\n/**\n* Returns a [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) notation\n* of a CSS property value.\n*\n* ```ts\n* getBoxSidesStyleShorthandValue( { top: '1px', right: '1px', bottom: '2px', left: '1px' } );\n* // will return '1px 1px 2px'\n* ```\n*/\nfunction getBoxSidesStyleShorthandValue({ top, right, bottom, left }) {\n\tconst out = [];\n\tif (left !== right) out.push(top, right, bottom, left);\n\telse if (bottom !== top) out.push(top, right, bottom);\n\telse if (right !== top) out.push(top, right);\n\telse out.push(top);\n\treturn out.join(\" \");\n}\n/**\n* Creates a normalizer for a [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) 1-to-4 value.\n*\n* ```ts\n* stylesProcessor.setNormalizer( 'margin', getPositionStyleShorthandNormalizer( 'margin' ) );\n* ```\n*/\nfunction getPositionStyleShorthandNormalizer(shorthand) {\n\treturn (value) => {\n\t\treturn {\n\t\t\tpath: shorthand,\n\t\t\tvalue: getBoxSidesStyleValues(value)\n\t\t};\n\t};\n}\n/**\n* Parses parts of a 1-to-4 value notation - handles some CSS values with spaces (like RGB()).\n*\n* ```ts\n* getShorthandStylesValues( 'red blue RGB(0, 0, 0)');\n* // will return [ 'red', 'blue', 'RGB(0, 0, 0)' ]\n* ```\n*/\nfunction getShorthandStylesValues(string) {\n\tconst matches = string.trim().slice(0, 1500).matchAll(CSS_SHORTHAND_VALUE_REGEXP);\n\treturn Array.from(matches).map((i) => i[0]);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/view/styles/background\n*/\n/**\n* CSS initial values for background longhand properties.\n*/\nconst BACKGROUND_INITIAL_ARRAY_VALUES = {\n\timage: \"none\",\n\trepeat: \"repeat\",\n\tposition: \"0% 0%\",\n\tsize: \"auto\",\n\torigin: \"padding-box\",\n\tclip: \"border-box\",\n\tattachment: \"scroll\"\n};\n/**\n* CSS function names that represent image values in the `background` shorthand.\n*/\nconst IMAGE_FUNCTIONS = [\n\t\"linear-gradient\",\n\t\"repeating-linear-gradient\",\n\t\"radial-gradient\",\n\t\"repeating-radial-gradient\",\n\t\"conic-gradient\",\n\t\"repeating-conic-gradient\",\n\t\"url\"\n];\n/**\n* Adds background CSS styles processing rules to the given `StylesProcessor`.\n*\n* Registers normalizers for the `background` shorthand and its longhand properties,\n* reducers that serialize them back to CSS strings, and the relation mapping between them.\n*\n* ```ts\n* editor.data.addStyleProcessorRules( addBackgroundStylesRules );\n* ```\n*\n* @param stylesProcessor The styles processor instance to register rules on.\n*/\nfunction addBackgroundStylesRules(stylesProcessor) {\n\tstylesProcessor.setNormalizer(\"background-color\", getBackgroundColorNormalizer());\n\tfor (const property in BACKGROUND_INITIAL_ARRAY_VALUES) {\n\t\tstylesProcessor.setNormalizer(`background-${property}`, getBackgroundArrayPropertyNormalizer(`background.${property}`));\n\t\tstylesProcessor.setReducer(`background-${property}`, getBackgroundArrayPropertyReducer(`background-${property}`));\n\t}\n\tstylesProcessor.setNormalizer(\"background\", getBackgroundNormalizer());\n\tstylesProcessor.setReducer(\"background\", getBackgroundReducer());\n\tstylesProcessor.setStyleRelation(\"background\", [\n\t\t\"background-color\",\n\t\t\"background-image\",\n\t\t\"background-repeat\",\n\t\t\"background-position\",\n\t\t\"background-size\",\n\t\t\"background-attachment\",\n\t\t\"background-origin\",\n\t\t\"background-clip\"\n\t]);\n}\n/**\n* Returns a normalizer for the `background` shorthand property.\n*\n* Parses the raw CSS value into comma-separated layers and merges them into\n* a structured `Background` object stored under the `background` path.\n*/\nfunction getBackgroundNormalizer() {\n\treturn (value) => {\n\t\tconst layers = parseBackgroundIntoLayers(value);\n\t\tif (!layers.length) layers.push({\n\t\t\t...getDefaultBackgroundLayer(),\n\t\t\tcolor: value\n\t\t});\n\t\treturn {\n\t\t\tpath: \"background\",\n\t\t\tvalue: normalizeBackgroundLayers(layers)\n\t\t};\n\t};\n}\n/**\n* Returns a normalizer for the `background-color` longhand property.\n*\n* Stores the raw color value directly under the `background.color` path.\n*/\nfunction getBackgroundColorNormalizer() {\n\treturn (value) => ({\n\t\tpath: \"background.color\",\n\t\tvalue\n\t});\n}\n/**\n* Returns a normalizer for a comma-separated background array longhand property\n* (e.g. `background-image`, `background-repeat`, `background-position`, `background-attachment`).\n*\n* Splits the raw value by top-level commas and stores the resulting array under the given path.\n*\n* @param path The target style path, e.g. `'background.image'`.\n*/\nfunction getBackgroundArrayPropertyNormalizer(path) {\n\treturn (value) => ({\n\t\tpath,\n\t\tvalue: splitByTopLevelCommas(value)\n\t});\n}\n/**\n* Returns a reducer for a comma-separated background array longhand property\n* (e.g. `background-image`, `background-repeat`, `background-position`, `background-attachment`).\n*\n* Serializes an array of per-layer values back into a comma-separated CSS string.\n*\n* @param property The CSS property name to output, e.g. `'background-image'`.\n*/\nfunction getBackgroundArrayPropertyReducer(property) {\n\treturn (value) => {\n\t\treturn [[property, value.join(\", \")]];\n\t};\n}\n/**\n* Returns a reducer for the `background` property. Depending on which longhand properties are present, it either:\n*\n* * Serializes into a concise `background` shorthand if all required longhand properties are present and non-empty, or\n* * Serializes into individual longhand properties for those that have defined values.\n*\n* This prevents overwriting external stylesheet rules with default values that were not explicitly set in the model.\n* For example, if only `background-color` is defined in the model, we emit just `background-color` rather than\n* the full `background` shorthand, which would reset all other sub-properties to their initial values.\n*/\nfunction getBackgroundReducer() {\n\treturn (value) => {\n\t\tconst background = value;\n\t\tif (Object.keys(BACKGROUND_INITIAL_ARRAY_VALUES).every((key) => {\n\t\t\tconst value = background[key];\n\t\t\treturn value !== void 0 && (!Array.isArray(value) || value.length > 0);\n\t\t})) return serializeToShorthandBackground(background);\n\t\treturn serializeToLonghandBackground(background);\n\t};\n}\n/**\n* Serializes a structured `Background` object into a concise CSS `background` shorthand string.\n*/\nfunction serializeToShorthandBackground(background) {\n\tconst result = [];\n\tconst shorthand = extractBackgroundLayers(background).map((layer) => serializeBackgroundLayer(layer).trim()).filter(Boolean).join(\", \");\n\tif (shorthand) result.push([\"background\", shorthand]);\n\treturn result;\n}\n/**\n* Serializes a structured `Background` object into individual CSS longhand properties for those that have defined values.\n* Each longhand property is serialized into a comma-separated string of per-layer values.\n*\n* This is used when not all required longhand properties are present, to avoid emitting default values for missing properties\n* and potentially overwriting external stylesheet rules.\n*/\nfunction serializeToLonghandBackground(background) {\n\tconst result = [];\n\tfor (const key in BACKGROUND_INITIAL_ARRAY_VALUES) {\n\t\tconst value = background[key];\n\t\tif (Array.isArray(value)) result.push([`background-${key}`, value.join(\", \")]);\n\t}\n\tif (background.color !== void 0) result.push([\"background-color\", background.color]);\n\treturn result;\n}\n/**\n* Serializes a single `BackgroundLayer` into a CSS background layer string.\n* Properties equal to their CSS initial values are omitted.\n*\n* @param layer A single background layer to serialize.\n* @returns A space-separated CSS string for the layer, or an empty string if no parts are present.\n*/\nfunction serializeBackgroundLayer(layer) {\n\tconst parts = [];\n\tif (layer.image && layer.image !== BACKGROUND_INITIAL_ARRAY_VALUES.image) parts.push(layer.image);\n\tconst positionStr = layer.position.join(\" \");\n\tconst isPositionDefault = !positionStr || positionStr === BACKGROUND_INITIAL_ARRAY_VALUES.position;\n\tif (!isPositionDefault) parts.push(positionStr);\n\tconst sizeStr = layer.size.join(\" \");\n\tif (!(!sizeStr || sizeStr === BACKGROUND_INITIAL_ARRAY_VALUES.size)) {\n\t\tif (isPositionDefault) parts.push(\"0% 0%\");\n\t\tparts.push(\"/\", sizeStr);\n\t}\n\tconst repeatStr = layer.repeat.join(\" \");\n\tif (repeatStr && repeatStr !== BACKGROUND_INITIAL_ARRAY_VALUES.repeat) parts.push(repeatStr);\n\tif (layer.attachment && layer.attachment !== BACKGROUND_INITIAL_ARRAY_VALUES.attachment) parts.push(layer.attachment);\n\tconst isOriginDefault = layer.origin === BACKGROUND_INITIAL_ARRAY_VALUES.origin;\n\tconst isClipDefault = layer.clip === BACKGROUND_INITIAL_ARRAY_VALUES.clip;\n\tif (!isOriginDefault || !isClipDefault) {\n\t\tparts.push(layer.origin);\n\t\tif (layer.clip !== layer.origin) parts.push(layer.clip);\n\t}\n\tif (layer.color) parts.push(layer.color);\n\treturn parts.join(\" \");\n}\n/**\n* Splits a structured `Background` object into an array of individual `BackgroundLayer` objects.\n*\n* The number of layers is determined by the longest array among the longhand properties.\n* The `color` value, if present, is always assigned to the last layer (per CSS spec).\n*\n* @param background The structured background object to split.\n* @returns An array of per-layer background objects.\n*\n* @example\n* // Input: { image: [ 'url(a.png)', 'url(b.png)' ], repeat: [ 'no-repeat', 'repeat' ], color: 'blue' }\n* // Output: [\n* // { image: 'url(a.png)', repeat: [ 'no-repeat' ] },\n* // { image: 'url(b.png)', repeat: [ 'repeat' ], color: 'blue' }\n* // ]\n*/\nfunction extractBackgroundLayers(background) {\n\tconst layerCount = getTotalBackgroundLayers(background);\n\tconst layers = Array.from({ length: layerCount }, (_, i) => {\n\t\tconst layer = getDefaultBackgroundLayer();\n\t\tif (background.image?.[i]) layer.image = background.image[i];\n\t\tif (background.position?.[i]) layer.position = background.position[i].split(\" \");\n\t\tif (background.size?.[i]) layer.size = background.size[i].split(\" \");\n\t\tif (background.repeat?.[i]) layer.repeat = background.repeat[i].split(\" \");\n\t\tif (background.attachment?.[i]) layer.attachment = background.attachment[i];\n\t\tif (background.origin?.[i]) layer.origin = background.origin[i];\n\t\tif (background.clip?.[i]) layer.clip = background.clip[i];\n\t\treturn layer;\n\t});\n\tif (background.color) layers.at(-1).color = background.color;\n\treturn layers;\n}\n/**\n* Determines the total number of background layers based on the longest array among the longhand properties in the `Background` object.\n*\n* @param background The structured background object to analyze.\n* @returns The total number of layers, which is the maximum length among the longhand property arrays.\n*/\nfunction getTotalBackgroundLayers(background) {\n\tlet layersCount = 0;\n\tfor (const value of Object.values(background)) if (Array.isArray(value) && value.length > layersCount) layersCount = value.length;\n\treturn layersCount;\n}\n/**\n* Merges an array of `BackgroundLayer` objects into a single structured `Background` object,\n* storing each longhand property as an array of per-layer values.\n*\n* Each input layer always has all properties defined (via `getDefaultBackgroundLayer`),\n* so the resulting arrays are fully populated for every layer.\n*\n* @param layers An array of parsed background layers.\n* @returns A merged `Background` object.\n*\n* @example\n* // Input: [ { image: 'url(a.png)', repeat: [ 'no-repeat' ], position: [ '0%', '0%' ], ... }, { image: 'none', color: 'red', ... } ]\n* // Output: {\n* // image: [ 'url(a.png)', 'none' ],\n* // position: [ '0% 0%', '0% 0%' ],\n* // repeat: [ 'no-repeat', 'repeat' ],\n* // ...\n* // color: 'red'\n* // }\n*/\nfunction normalizeBackgroundLayers(layers) {\n\tconst background = {\n\t\timage: [],\n\t\tposition: [],\n\t\tsize: [],\n\t\trepeat: [],\n\t\tattachment: [],\n\t\torigin: [],\n\t\tclip: []\n\t};\n\tfor (const layer of layers) {\n\t\tbackground.position.push(layer.position.join(\" \"));\n\t\tbackground.size.push(layer.size.join(\" \"));\n\t\tbackground.repeat.push(layer.repeat.join(\" \"));\n\t\tbackground.image.push(layer.image);\n\t\tbackground.attachment.push(layer.attachment);\n\t\tbackground.origin.push(layer.origin);\n\t\tbackground.clip.push(layer.clip);\n\t}\n\tif (layers.at(-1)?.color) background.color = layers.at(-1).color;\n\treturn background;\n}\n/**\n* Parses a raw CSS `background` value and splits it into an array of `BackgroundLayer` objects,\n* one per comma-separated layer.\n*\n* The CSS `background` shorthand syntax is:\n* `background: [ <bg-layer> , ]* <final-bg-layer>`\n*\n* Commas inside function calls (e.g. `rgba()`, `linear-gradient()`) are correctly ignored\n* during splitting.\n*\n* @param value The raw CSS background value string.\n* @returns An array of parsed background layers.\n*\n* @example\n* splitBackgroundIntoLayers( 'url(a.png) no-repeat, red' );\n* // → [ { image: 'url(a.png)', repeat: [ 'no-repeat' ] }, { color: 'red' } ]\n*/\nfunction parseBackgroundIntoLayers(value) {\n\treturn splitByTopLevelCommas(value).map(parseBackgroundLayer).filter((obj) => obj !== null);\n}\n/**\n* Parses a single CSS background layer string into a structured `BackgroundLayer` object.\n*\n* First extracts any image function (gradient or `url()`), then classifies the remaining\n* space-separated tokens as repeat, position, attachment, or color values.\n*\n* @param layer A single (non-comma-separated) background layer string.\n* @returns A structured background layer object. If no valid properties were found, returns `null`.\n*\n* @example\n* parseBackgroundLayer( 'url(bg.png) top left no-repeat fixed' );\n* // → { image: 'url(bg.png)', position: [ 'top', 'left' ], repeat: [ 'no-repeat' ], attachment: 'fixed' }\n*/\nfunction parseBackgroundLayer(layer) {\n\tconst background = {};\n\tconst { value: valueWithoutImage, image } = extractBackgroundImage(layer);\n\tconst parts = getShorthandStylesValues(valueWithoutImage);\n\tif (image) background.image = image;\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tif (part === \"/\") {\n\t\t\tbackground.size = [];\n\t\t\twhile (i + 1 < parts.length && isSizeStyleValue(parts[i + 1])) background.size.push(parts[++i]);\n\t\t} else if (isRepeatStyleValue(part)) {\n\t\t\tbackground.repeat ||= [];\n\t\t\tbackground.repeat.push(part);\n\t\t} else if (isPositionStyleValue(part) || isPercentageStyleValue(part)) {\n\t\t\tbackground.position ||= [];\n\t\t\tbackground.position.push(part);\n\t\t\tif (i + 1 < parts.length && isPercentageStyleValue(part) && isPercentageStyleValue(parts[i + 1])) background.position.push(parts[++i]);\n\t\t} else if (isAttachmentStyleValue(part)) background.attachment = part;\n\t\telse if (isClipStyleValue(part)) if (isOriginStyleValue(part) && !background.origin) {\n\t\t\tbackground.origin = part;\n\t\t\tbackground.clip = part;\n\t\t} else background.clip = part;\n\t\telse if (isColorStyleValue(part)) background.color = part;\n\t}\n\tif (isEmpty(background)) return null;\n\treturn {\n\t\t...getDefaultBackgroundLayer(),\n\t\t...background\n\t};\n}\n/**\n* Returns a `BackgroundLayer` object with all properties set to their CSS initial values.\n*\n* Used as the base when parsing the `background` shorthand so that every property of a parsed\n* layer always has a defined value.\n*\n* @returns A background layer with default values.\n*/\nfunction getDefaultBackgroundLayer() {\n\treturn {\n\t\tattachment: BACKGROUND_INITIAL_ARRAY_VALUES.attachment,\n\t\timage: BACKGROUND_INITIAL_ARRAY_VALUES.image,\n\t\torigin: BACKGROUND_INITIAL_ARRAY_VALUES.origin,\n\t\tclip: BACKGROUND_INITIAL_ARRAY_VALUES.clip,\n\t\tposition: BACKGROUND_INITIAL_ARRAY_VALUES.position.split(\" \"),\n\t\trepeat: BACKGROUND_INITIAL_ARRAY_VALUES.repeat.split(\" \"),\n\t\tsize: BACKGROUND_INITIAL_ARRAY_VALUES.size.split(\" \")\n\t};\n}\n/**\n* Extracts the first CSS image function (`linear-gradient`, `url`, etc.) from a raw CSS value string\n* and returns it separately along with the remaining string with the image function removed.\n*\n* Handles arbitrarily nested parentheses correctly (e.g. `rgba()` inside a gradient).\n* Only one image function is extracted per call — the caller is responsible for looping\n* if multiple image functions may be present.\n*\n* @param value The raw CSS value string to process.\n* @returns An object with `value` (the string with the image function removed) and\n* `image` (the extracted function string, or `null` if none was found).\n*\n* @example\n* extractBackgroundImage( 'linear-gradient(red, blue) no-repeat' );\n* // → { value: ' no-repeat', image: 'linear-gradient(red, blue)' }\n*/\nfunction extractBackgroundImage(value) {\n\tfor (const imageFunction of IMAGE_FUNCTIONS) {\n\t\tconst prefix = imageFunction + \"(\";\n\t\tconst firstIndex = value.indexOf(prefix);\n\t\tif (firstIndex < 0) continue;\n\t\tlet acc = imageFunction;\n\t\tlet nesting = 0;\n\t\tfor (let i = firstIndex + imageFunction.length; i < value.length; i++) {\n\t\t\tconst char = value[i];\n\t\t\tif (char === \"(\") nesting++;\n\t\t\telse if (char === \")\") nesting--;\n\t\t\tacc += char;\n\t\t\tif (nesting === 0) return {\n\t\t\t\tvalue: value.slice(0, firstIndex) + value.slice(i + 1),\n\t\t\t\timage: acc\n\t\t\t};\n\t\t}\n\t}\n\tif (value.includes(\"none\")) return {\n\t\tvalue: value.replace(\"none\", \"\"),\n\t\timage: \"none\"\n\t};\n\treturn {\n\t\tvalue,\n\t\timage: null\n\t};\n}\n/**\n* Splits a CSS value string by commas that are at the top level (i.e. not inside parentheses).\n*\n* This is necessary because commas appear both as layer separators in the `background` shorthand\n* and as argument separators inside functions like `rgba()` or `linear-gradient()`.\n*\n* @param value The CSS value string to split.\n* @returns An array of trimmed top-level comma-separated segments.\n*\n* @example\n* splitByTopLevelCommas( 'linear-gradient(red, blue), center' );\n* // → [ 'linear-gradient(red, blue)', 'center' ]\n*/\nfunction splitByTopLevelCommas(value) {\n\tconst parts = [];\n\tlet current = \"\";\n\tlet nesting = 0;\n\tfor (const char of value) {\n\t\tif (char === \"(\") nesting++;\n\t\telse if (char === \")\") nesting--;\n\t\telse if (char === \",\" && nesting === 0) {\n\t\t\tparts.push(current.trim());\n\t\t\tcurrent = \"\";\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent += char;\n\t}\n\tif (current.trim()) parts.push(current.trim());\n\treturn parts;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Adds a border CSS styles processing rules.\n*\n* ```ts\n* editor.data.addStyleProcessorRules( addBorderStylesRules );\n* ```\n*\n* This rules merges all [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) styles notation shorthands:\n*\n* - border\n* - border-top\n* - border-right\n* - border-bottom\n* - border-left\n* - border-color\n* - border-style\n* - border-width\n*\n* and all corresponding longhand forms (like `border-top-color`, `border-top-style`, etc).\n*\n* It does not handle other shorthands (like `border-radius` or `border-image`).\n*/\nfunction addBorderStylesRules(stylesProcessor) {\n\tstylesProcessor.setNormalizer(\"border\", getBorderNormalizer());\n\tstylesProcessor.setNormalizer(\"border-top\", getBorderPositionNormalizer(\"top\"));\n\tstylesProcessor.setNormalizer(\"border-right\", getBorderPositionNormalizer(\"right\"));\n\tstylesProcessor.setNormalizer(\"border-bottom\", getBorderPositionNormalizer(\"bottom\"));\n\tstylesProcessor.setNormalizer(\"border-left\", getBorderPositionNormalizer(\"left\"));\n\tstylesProcessor.setNormalizer(\"border-color\", getBorderPropertyNormalizer(\"color\"));\n\tstylesProcessor.setNormalizer(\"border-width\", getBorderPropertyNormalizer(\"width\"));\n\tstylesProcessor.setNormalizer(\"border-style\", getBorderPropertyNormalizer(\"style\"));\n\tstylesProcessor.setNormalizer(\"border-top-color\", getBorderPropertyPositionNormalizer(\"color\", \"top\"));\n\tstylesProcessor.setNormalizer(\"border-top-style\", getBorderPropertyPositionNormalizer(\"style\", \"top\"));\n\tstylesProcessor.setNormalizer(\"border-top-width\", getBorderPropertyPositionNormalizer(\"width\", \"top\"));\n\tstylesProcessor.setNormalizer(\"border-right-color\", getBorderPropertyPositionNormalizer(\"color\", \"right\"));\n\tstylesProcessor.setNormalizer(\"border-right-style\", getBorderPropertyPositionNormalizer(\"style\", \"right\"));\n\tstylesProcessor.setNormalizer(\"border-right-width\", getBorderPropertyPositionNormalizer(\"width\", \"right\"));\n\tstylesProcessor.setNormalizer(\"border-bottom-color\", getBorderPropertyPositionNormalizer(\"color\", \"bottom\"));\n\tstylesProcessor.setNormalizer(\"border-bottom-style\", getBorderPropertyPositionNormalizer(\"style\", \"bottom\"));\n\tstylesProcessor.setNormalizer(\"border-bottom-width\", getBorderPropertyPositionNormalizer(\"width\", \"bottom\"));\n\tstylesProcessor.setNormalizer(\"border-left-color\", getBorderPropertyPositionNormalizer(\"color\", \"left\"));\n\tstylesProcessor.setNormalizer(\"border-left-style\", getBorderPropertyPositionNormalizer(\"style\", \"left\"));\n\tstylesProcessor.setNormalizer(\"border-left-width\", getBorderPropertyPositionNormalizer(\"width\", \"left\"));\n\tstylesProcessor.setExtractor(\"border-top\", getBorderPositionExtractor(\"top\"));\n\tstylesProcessor.setExtractor(\"border-right\", getBorderPositionExtractor(\"right\"));\n\tstylesProcessor.setExtractor(\"border-bottom\", getBorderPositionExtractor(\"bottom\"));\n\tstylesProcessor.setExtractor(\"border-left\", getBorderPositionExtractor(\"left\"));\n\tstylesProcessor.setExtractor(\"border-top-color\", \"border.color.top\");\n\tstylesProcessor.setExtractor(\"border-right-color\", \"border.color.right\");\n\tstylesProcessor.setExtractor(\"border-bottom-color\", \"border.color.bottom\");\n\tstylesProcessor.setExtractor(\"border-left-color\", \"border.color.left\");\n\tstylesProcessor.setExtractor(\"border-top-width\", \"border.width.top\");\n\tstylesProcessor.setExtractor(\"border-right-width\", \"border.width.right\");\n\tstylesProcessor.setExtractor(\"border-bottom-width\", \"border.width.bottom\");\n\tstylesProcessor.setExtractor(\"border-left-width\", \"border.width.left\");\n\tstylesProcessor.setExtractor(\"border-top-style\", \"border.style.top\");\n\tstylesProcessor.setExtractor(\"border-right-style\", \"border.style.right\");\n\tstylesProcessor.setExtractor(\"border-bottom-style\", \"border.style.bottom\");\n\tstylesProcessor.setExtractor(\"border-left-style\", \"border.style.left\");\n\tstylesProcessor.setReducer(\"border-color\", getBoxSidesStyleValueReducer(\"border-color\"));\n\tstylesProcessor.setReducer(\"border-style\", getBoxSidesStyleValueReducer(\"border-style\"));\n\tstylesProcessor.setReducer(\"border-width\", getBoxSidesStyleValueReducer(\"border-width\"));\n\tstylesProcessor.setReducer(\"border-top\", getBorderPositionReducer(\"top\"));\n\tstylesProcessor.setReducer(\"border-right\", getBorderPositionReducer(\"right\"));\n\tstylesProcessor.setReducer(\"border-bottom\", getBorderPositionReducer(\"bottom\"));\n\tstylesProcessor.setReducer(\"border-left\", getBorderPositionReducer(\"left\"));\n\tstylesProcessor.setReducer(\"border\", getBorderReducer());\n\tstylesProcessor.setStyleRelation(\"border\", [\n\t\t\"border-color\",\n\t\t\"border-style\",\n\t\t\"border-width\",\n\t\t\"border-top\",\n\t\t\"border-right\",\n\t\t\"border-bottom\",\n\t\t\"border-left\",\n\t\t\"border-top-color\",\n\t\t\"border-right-color\",\n\t\t\"border-bottom-color\",\n\t\t\"border-left-color\",\n\t\t\"border-top-style\",\n\t\t\"border-right-style\",\n\t\t\"border-bottom-style\",\n\t\t\"border-left-style\",\n\t\t\"border-top-width\",\n\t\t\"border-right-width\",\n\t\t\"border-bottom-width\",\n\t\t\"border-left-width\"\n\t]);\n\tstylesProcessor.setStyleRelation(\"border-color\", [\n\t\t\"border-top-color\",\n\t\t\"border-right-color\",\n\t\t\"border-bottom-color\",\n\t\t\"border-left-color\"\n\t]);\n\tstylesProcessor.setStyleRelation(\"border-style\", [\n\t\t\"border-top-style\",\n\t\t\"border-right-style\",\n\t\t\"border-bottom-style\",\n\t\t\"border-left-style\"\n\t]);\n\tstylesProcessor.setStyleRelation(\"border-width\", [\n\t\t\"border-top-width\",\n\t\t\"border-right-width\",\n\t\t\"border-bottom-width\",\n\t\t\"border-left-width\"\n\t]);\n\tstylesProcessor.setStyleRelation(\"border-top\", [\n\t\t\"border-top-color\",\n\t\t\"border-top-style\",\n\t\t\"border-top-width\"\n\t]);\n\tstylesProcessor.setStyleRelation(\"border-right\", [\n\t\t\"border-right-color\",\n\t\t\"border-right-style\",\n\t\t\"border-right-width\"\n\t]);\n\tstylesProcessor.setStyleRelation(\"border-bottom\", [\n\t\t\"border-bottom-color\",\n\t\t\"border-bottom-style\",\n\t\t\"border-bottom-width\"\n\t]);\n\tstylesProcessor.setStyleRelation(\"border-left\", [\n\t\t\"border-left-color\",\n\t\t\"border-left-style\",\n\t\t\"border-left-width\"\n\t]);\n}\nfunction getBorderNormalizer() {\n\treturn (value) => {\n\t\tconst { color, style, width } = normalizeBorderShorthand(value);\n\t\treturn {\n\t\t\tpath: \"border\",\n\t\t\tvalue: {\n\t\t\t\tcolor: getBoxSidesStyleValues(color),\n\t\t\t\tstyle: getBoxSidesStyleValues(style),\n\t\t\t\twidth: getBoxSidesStyleValues(width)\n\t\t\t}\n\t\t};\n\t};\n}\nfunction getBorderPositionNormalizer(side) {\n\treturn (value) => {\n\t\tconst { color, style, width } = normalizeBorderShorthand(value);\n\t\tconst border = {};\n\t\tif (color !== void 0) border.color = { [side]: color };\n\t\tif (style !== void 0) border.style = { [side]: style };\n\t\tif (width !== void 0) border.width = { [side]: width };\n\t\treturn {\n\t\t\tpath: \"border\",\n\t\t\tvalue: border\n\t\t};\n\t};\n}\nfunction getBorderPropertyNormalizer(propertyName) {\n\treturn (value) => {\n\t\treturn {\n\t\t\tpath: \"border\",\n\t\t\tvalue: toBorderPropertyShorthand(value, propertyName)\n\t\t};\n\t};\n}\nfunction toBorderPropertyShorthand(value, property) {\n\treturn { [property]: getBoxSidesStyleValues(value) };\n}\nfunction getBorderPropertyPositionNormalizer(property, side) {\n\treturn (value) => {\n\t\treturn {\n\t\t\tpath: \"border\",\n\t\t\tvalue: { [property]: { [side]: value } }\n\t\t};\n\t};\n}\nfunction getBorderPositionExtractor(which) {\n\treturn (name, styles) => {\n\t\tif (styles.border) return extractBorderPosition(styles.border, which);\n\t};\n}\nfunction extractBorderPosition(border, which) {\n\tconst value = {};\n\tif (border.width && border.width[which]) value.width = border.width[which];\n\tif (border.style && border.style[which]) value.style = border.style[which];\n\tif (border.color && border.color[which]) value.color = border.color[which];\n\treturn value;\n}\nfunction normalizeBorderShorthand(string) {\n\tconst result = {};\n\tconst parts = getShorthandStylesValues(string);\n\tfor (const part of parts) if (isLengthStyleValue(part) || /thin|medium|thick/.test(part)) result.width = part;\n\telse if (isLineStyleValue(part)) result.style = part;\n\telse result.color = part;\n\treturn result;\n}\n/**\n* The border reducer factory.\n*\n* It tries to produce the most optimal output for the specified styles.\n*\n* For a border style:\n*\n* ```css\n* style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n* ```\n*\n* It will produce: `border-style: solid`.\n* For a border style and color:\n*\n* ```css\n* color: {top: \"#ff0\", bottom: \"#ff0\", right: \"#ff0\", left: \"#ff0\"}\n* style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n* ```\n*\n* It will produce: `border-color: #ff0; border-style: solid`.\n* If all border parameters are specified:\n*\n* ```css\n* color: {top: \"#ff0\", bottom: \"#ff0\", right: \"#ff0\", left: \"#ff0\"}\n* style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n* width: {top: \"2px\", bottom: \"2px\", right: \"2px\", left: \"2px\"}\n* ```\n*\n* It will combine everything into a single property: `border: 2px solid #ff0`.\n*\n* The definitions are merged only if all border selectors have the same values.\n*/\nfunction getBorderReducer() {\n\treturn (value) => {\n\t\tconst topStyles = extractBorderPosition(value, \"top\");\n\t\tconst rightStyles = extractBorderPosition(value, \"right\");\n\t\tconst bottomStyles = extractBorderPosition(value, \"bottom\");\n\t\tconst leftStyles = extractBorderPosition(value, \"left\");\n\t\tconst borderStyles = [\n\t\t\ttopStyles,\n\t\t\trightStyles,\n\t\t\tbottomStyles,\n\t\t\tleftStyles\n\t\t];\n\t\tconst borderStylesByType = {\n\t\t\twidth: getReducedStyleValueForType(borderStyles, \"width\"),\n\t\t\tstyle: getReducedStyleValueForType(borderStyles, \"style\"),\n\t\t\tcolor: getReducedStyleValueForType(borderStyles, \"color\")\n\t\t};\n\t\tconst reducedBorderStyle = reduceBorderPosition(borderStylesByType, \"all\");\n\t\tif (reducedBorderStyle.length) return reducedBorderStyle;\n\t\treturn [\n\t\t\t...Object.entries(borderStylesByType).reduce((reducedStyleTypes, [type, value]) => {\n\t\t\t\tif (value) {\n\t\t\t\t\treducedStyleTypes.push([`border-${type}`, value]);\n\t\t\t\t\tborderStyles.forEach((style) => delete style[type]);\n\t\t\t\t}\n\t\t\t\treturn reducedStyleTypes;\n\t\t\t}, []),\n\t\t\t...reduceBorderPosition(topStyles, \"top\"),\n\t\t\t...reduceBorderPosition(rightStyles, \"right\"),\n\t\t\t...reduceBorderPosition(bottomStyles, \"bottom\"),\n\t\t\t...reduceBorderPosition(leftStyles, \"left\")\n\t\t];\n\t};\n\t/**\n\t* @param styles The array of objects with `style`, `color`, `width` properties.\n\t*/\n\tfunction getReducedStyleValueForType(styles, type) {\n\t\treturn styles.map((style) => style[type]).reduce((result, style) => result == style ? result : null);\n\t}\n}\nfunction getBorderPositionReducer(which) {\n\treturn (value) => reduceBorderPosition(value, which);\n}\n/**\n* Returns an array with reduced border styles depending on the specified values.\n*\n* If all border properties (width, style, color) are specified, the returned selector will be\n* merged into a group: `border-*: [width] [style] [color]`.\n*\n* Otherwise, the specific definitions will be returned: `border-(width|style|color)-*: [value]`.\n*\n* @param value Styles if defined.\n* @param which The border position.\n*/\nfunction reduceBorderPosition(value, which) {\n\tconst borderTypes = [];\n\tif (value && value.width) borderTypes.push(\"width\");\n\tif (value && value.style) borderTypes.push(\"style\");\n\tif (value && value.color) borderTypes.push(\"color\");\n\tif (borderTypes.length == 3) {\n\t\tconst borderValue = borderTypes.map((item) => value[item]).join(\" \");\n\t\treturn [which == \"all\" ? [\"border\", borderValue] : [`border-${which}`, borderValue]];\n\t}\n\tif (which == \"all\") return [];\n\treturn borderTypes.map((type) => {\n\t\treturn [`border-${which}-${type}`, value[type]];\n\t});\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Adds a margin CSS styles processing rules.\n*\n* ```ts\n* editor.data.addStyleProcessorRules( addMarginStylesRules );\n* ```\n*/\nfunction addMarginStylesRules(stylesProcessor) {\n\tstylesProcessor.setNormalizer(\"margin\", getPositionStyleShorthandNormalizer(\"margin\"));\n\tstylesProcessor.setNormalizer(\"margin-top\", (value) => ({\n\t\tpath: \"margin.top\",\n\t\tvalue\n\t}));\n\tstylesProcessor.setNormalizer(\"margin-right\", (value) => ({\n\t\tpath: \"margin.right\",\n\t\tvalue\n\t}));\n\tstylesProcessor.setNormalizer(\"margin-bottom\", (value) => ({\n\t\tpath: \"margin.bottom\",\n\t\tvalue\n\t}));\n\tstylesProcessor.setNormalizer(\"margin-left\", (value) => ({\n\t\tpath: \"margin.left\",\n\t\tvalue\n\t}));\n\tstylesProcessor.setReducer(\"margin\", getBoxSidesStyleValueReducer(\"margin\"));\n\tstylesProcessor.setStyleRelation(\"margin\", [\n\t\t\"margin-top\",\n\t\t\"margin-right\",\n\t\t\"margin-bottom\",\n\t\t\"margin-left\"\n\t]);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Adds a padding CSS styles processing rules.\n*\n* ```ts\n* editor.data.addStyleProcessorRules( addPaddingStylesRules );\n* ```\n*/\nfunction addPaddingStylesRules(stylesProcessor) {\n\tstylesProcessor.setNormalizer(\"padding\", getPositionStyleShorthandNormalizer(\"padding\"));\n\tstylesProcessor.setNormalizer(\"padding-top\", (value) => ({\n\t\tpath: \"padding.top\",\n\t\tvalue\n\t}));\n\tstylesProcessor.setNormalizer(\"padding-right\", (value) => ({\n\t\tpath: \"padding.right\",\n\t\tvalue\n\t}));\n\tstylesProcessor.setNormalizer(\"padding-bottom\", (value) => ({\n\t\tpath: \"padding.bottom\",\n\t\tvalue\n\t}));\n\tstylesProcessor.setNormalizer(\"padding-left\", (value) => ({\n\t\tpath: \"padding.left\",\n\t\tvalue\n\t}));\n\tstylesProcessor.setReducer(\"padding\", getBoxSidesStyleValueReducer(\"padding\"));\n\tstylesProcessor.setStyleRelation(\"padding\", [\n\t\t\"padding-top\",\n\t\t\"padding-right\",\n\t\t\"padding-bottom\",\n\t\t\"padding-left\"\n\t]);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/dev-utils/view\n*/\n/**\n* Collection of methods for manipulating the {@link module:engine/view/view view} for testing purposes.\n*/\nconst ELEMENT_RANGE_START_TOKEN = \"[\";\nconst ELEMENT_RANGE_END_TOKEN = \"]\";\nconst TEXT_RANGE_START_TOKEN = \"{\";\nconst TEXT_RANGE_END_TOKEN = \"}\";\nconst allowedTypes = {\n\t\"container\": ViewContainerElement,\n\t\"attribute\": ViewAttributeElement,\n\t\"empty\": ViewEmptyElement,\n\t\"ui\": ViewUIElement,\n\t\"raw\": ViewRawElement\n};\nconst domConverterStub = { setContentOf: (node, html) => {\n\tnode.innerHTML = html;\n} };\n/**\n* Writes the content of the {@link module:engine/view/document~ViewDocument document} to an HTML-like string.\n*\n* @param view The view to stringify.\n* @param options.withoutSelection Whether to write the selection. When set to `true`, the selection will\n* not be included in the returned string.\n* @param options.rootName The name of the root from which the data should be stringified. If not provided,\n* the default `main` name will be used.\n* @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n* instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n* @param options.showPriority When set to `true`, the attribute element's priority will be printed\n* (`<span view-priority=\"12\">`, `<b view-priority=\"10\">`).\n* @param options.renderUIElements When set to `true`, the inner content of each\n* {@link module:engine/view/uielement~ViewUIElement} will be printed.\n* @param options.renderRawElements When set to `true`, the inner content of each\n* {@link module:engine/view/rawelement~ViewRawElement} will be printed.\n* @param options.domConverter When set to an actual {@link module:engine/view/domconverter~ViewDomConverter ViewDomConverter}\n* instance, it lets the conversion go through exactly the same flow the editing view is going through,\n* i.e. with view data filtering. Otherwise the simple stub is used.\n* @returns The stringified data.\n*/\nconst _getViewData = /* #__PURE__ */ (() => {\n\tconst getViewData = function(view, options = {}) {\n\t\tif (!(view instanceof EditingView)) throw new TypeError(\"View needs to be an instance of module:engine/view/view~EditingView.\");\n\t\tconst document = view.document;\n\t\tconst withoutSelection = !!options.withoutSelection;\n\t\tconst rootName = options.rootName || \"main\";\n\t\tconst root = document.getRoot(rootName);\n\t\tconst stringifyOptions = {\n\t\t\tshowType: options.showType,\n\t\t\tshowPriority: options.showPriority,\n\t\t\trenderUIElements: options.renderUIElements,\n\t\t\trenderRawElements: options.renderRawElements,\n\t\t\tignoreRoot: true,\n\t\t\tdomConverter: options.domConverter,\n\t\t\tskipListItemIds: options.skipListItemIds\n\t\t};\n\t\treturn withoutSelection ? getViewData._stringify(root, null, stringifyOptions) : getViewData._stringify(root, document.selection, stringifyOptions);\n\t};\n\tgetViewData._stringify = _stringifyView;\n\treturn getViewData;\n})();\n/**\n* Sets the content of a view {@link module:engine/view/document~ViewDocument document} provided as an HTML-like string.\n*\n* @param data An HTML-like string to write into the document.\n* @param options.rootName The root name where _parseViewd data will be stored. If not provided,\n* the default `main` name will be used.\n*/\nconst _setViewData = /* #__PURE__ */ (() => {\n\tconst setViewData = function(view, data, options = {}) {\n\t\tif (!(view instanceof EditingView)) throw new TypeError(\"View needs to be an instance of module:engine/view/view~EditingView.\");\n\t\tconst document = view.document;\n\t\tconst rootName = options.rootName || \"main\";\n\t\tconst root = document.getRoot(rootName);\n\t\tview.change((writer) => {\n\t\t\tconst result = setViewData._parse(data, { rootElement: root });\n\t\t\tif (result.view && result.selection) writer.setSelection(result.selection);\n\t\t});\n\t};\n\tsetViewData._parse = _parseView;\n\treturn setViewData;\n})();\n/**\n* Converts view elements to HTML-like string representation.\n*\n* A root element can be provided as {@link module:engine/view/text~ViewText text}:\n*\n* ```ts\n* const text = downcastWriter.createText( 'foobar' );\n* stringify( text ); // 'foobar'\n* ```\n*\n* or as an {@link module:engine/view/element~ViewElement element}:\n*\n* ```ts\n* const element = downcastWriter.createElement( 'p', null, downcastWriter.createText( 'foobar' ) );\n* stringify( element ); // '<p>foobar</p>'\n* ```\n*\n* or as a {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment}:\n*\n* ```ts\n* const text = downcastWriter.createText( 'foobar' );\n* const b = downcastWriter.createElement( 'b', { name: 'test' }, text );\n* const p = downcastWriter.createElement( 'p', { style: 'color:red;' } );\n* const fragment = downcastWriter.createDocumentFragment( [ p, b ] );\n*\n* stringify( fragment ); // '<p style=\"color:red;\"></p><b name=\"test\">foobar</b>'\n* ```\n*\n* Additionally, a {@link module:engine/view/documentselection~ViewDocumentSelection selection} instance can be provided.\n* Ranges from the selection will then be included in the output data.\n* If a range position is placed inside the element node, it will be represented with `[` and `]`:\n*\n* ```ts\n* const text = downcastWriter.createText( 'foobar' );\n* const b = downcastWriter.createElement( 'b', null, text );\n* const p = downcastWriter.createElement( 'p', null, b );\n* const selection = downcastWriter.createSelection(\n* \tdowncastWriter.createRangeIn( p )\n* );\n*\n* stringify( p, selection ); // '<p>[<b>foobar</b>]</p>'\n* ```\n*\n* If a range is placed inside the text node, it will be represented with `{` and `}`:\n*\n* ```ts\n* const text = downcastWriter.createText( 'foobar' );\n* const b = downcastWriter.createElement( 'b', null, text );\n* const p = downcastWriter.createElement( 'p', null, b );\n* const selection = downcastWriter.createSelection(\n* \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 1 ), downcastWriter.createPositionAt( text, 5 ) )\n* );\n*\n* stringify( p, selection ); // '<p><b>f{ooba}r</b></p>'\n* ```\n*\n* ** Note: **\n* It is possible to unify selection markers to `[` and `]` for both (inside and outside text)\n* by setting the `sameSelectionCharacters=true` option. It is mainly used when the view stringify option is used by\n* model utilities.\n*\n* Multiple ranges are supported:\n*\n* ```ts\n* const text = downcastWriter.createText( 'foobar' );\n* const selection = downcastWriter.createSelection( [\n* \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 0 ), downcastWriter.createPositionAt( text, 1 ) ),\n* \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 3 ), downcastWriter.createPositionAt( text, 5 ) )\n* ] );\n*\n* stringify( text, selection ); // '{f}oo{ba}r'\n* ```\n*\n* A {@link module:engine/view/range~ViewRange range} or {@link module:engine/view/position~ViewPosition position} instance can be provided\n* instead of the {@link module:engine/view/documentselection~ViewDocumentSelection selection} instance. If a range instance\n* is provided, it will be converted to a selection containing this range. If a position instance is provided, it will\n* be converted to a selection containing one range collapsed at this position.\n*\n* ```ts\n* const text = downcastWriter.createText( 'foobar' );\n* const range = downcastWriter.createRange( downcastWriter.createPositionAt( text, 0 ), downcastWriter.createPositionAt( text, 1 ) );\n* const position = downcastWriter.createPositionAt( text, 3 );\n*\n* stringify( text, range ); // '{f}oobar'\n* stringify( text, position ); // 'foo{}bar'\n* ```\n*\n* An additional `options` object can be provided.\n* If `options.showType` is set to `true`, element's types will be\n* presented for {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements},\n* {@link module:engine/view/containerelement~ViewContainerElement container elements}\n* {@link module:engine/view/emptyelement~ViewEmptyElement empty elements}\n* and {@link module:engine/view/uielement~ViewUIElement UI elements}:\n*\n* ```ts\n* const attribute = downcastWriter.createAttributeElement( 'b' );\n* const container = downcastWriter.createContainerElement( 'p' );\n* const empty = downcastWriter.createEmptyElement( 'img' );\n* const ui = downcastWriter.createUIElement( 'span' );\n* getData( attribute, null, { showType: true } ); // '<attribute:b></attribute:b>'\n* getData( container, null, { showType: true } ); // '<container:p></container:p>'\n* getData( empty, null, { showType: true } ); // '<empty:img></empty:img>'\n* getData( ui, null, { showType: true } ); // '<ui:span></ui:span>'\n* ```\n*\n* If `options.showPriority` is set to `true`, a priority will be displayed for all\n* {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements}.\n*\n* ```ts\n* const attribute = downcastWriter.createAttributeElement( 'b' );\n* attribute._priority = 20;\n* getData( attribute, null, { showPriority: true } ); // <b view-priority=\"20\"></b>\n* ```\n*\n* If `options.showAttributeElementId` is set to `true`, the attribute element's id will be displayed for all\n* {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements} that have it set.\n*\n* ```ts\n* const attribute = downcastWriter.createAttributeElement( 'span' );\n* attribute._id = 'marker:foo';\n* getData( attribute, null, { showAttributeElementId: true } ); // <span view-id=\"marker:foo\"></span>\n* ```\n*\n* @param node The node to stringify.\n* @param selectionOrPositionOrRange A selection instance whose ranges will be included in the returned string data.\n* If a range instance is provided, it will be converted to a selection containing this range. If a position instance\n* is provided, it will be converted to a selection containing one range collapsed at this position.\n* @param options An object with additional options.\n* @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n* instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n* @param options.showPriority When set to `true`, the attribute element's priority will be printed\n* (`<span view-priority=\"12\">`, `<b view-priority=\"10\">`).\n* @param options.showAttributeElementId When set to `true`, attribute element's id will be printed\n* (`<span id=\"marker:foo\">`).\n* @param options.ignoreRoot When set to `true`, the root's element opening and closing will not be printed.\n* Mainly used by the `getData` function to ignore the {@link module:engine/view/document~ViewDocument document's} root element.\n* @param options.sameSelectionCharacters When set to `true`, the selection inside the text will be marked as\n* `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both will be marked as `[` and `]` only.\n* @param options.renderUIElements When set to `true`, the inner content of each\n* {@link module:engine/view/uielement~ViewUIElement} will be printed.\n* @param options.renderRawElements When set to `true`, the inner content of each\n* {@link module:engine/view/rawelement~ViewRawElement} will be printed.\n* @param options.domConverter When set to an actual {@link module:engine/view/domconverter~ViewDomConverter ViewDomConverter}\n* instance, it lets the conversion go through exactly the same flow the editing view is going through,\n* i.e. with view data filtering. Otherwise the simple stub is used.\n* @returns An HTML-like string representing the view.\n*/\nfunction _stringifyView(node, selectionOrPositionOrRange = null, options = {}) {\n\tlet selection;\n\tif (selectionOrPositionOrRange instanceof ViewPosition || selectionOrPositionOrRange instanceof ViewRange) selection = new ViewDocumentSelection(selectionOrPositionOrRange);\n\telse selection = selectionOrPositionOrRange;\n\treturn new ViewStringify(node, selection, options).stringify();\n}\n/**\n* Parses an HTML-like string and returns a view tree.\n* A simple string will be converted to a {@link module:engine/view/text~ViewText text} node:\n*\n* ```ts\n* _parseView( 'foobar' ); // Returns an instance of text.\n* ```\n*\n* {@link module:engine/view/element~ViewElement Elements} will be _parseViewd with attributes as children:\n*\n* ```ts\n* _parseView( '<b name=\"baz\">foobar</b>' ); // Returns an instance of element with the `baz` attribute and a text child node.\n* ```\n*\n* Multiple nodes provided on root level will be converted to a\n* {@link module:engine/view/documentfragment~ViewDocumentFragment document fragment}:\n*\n* ```ts\n* _parseView( '<b>foo</b><i>bar</i>' ); // Returns a document fragment with two child elements.\n* ```\n*\n* The method can _parseView multiple {@link module:engine/view/range~ViewRange ranges} provided in string data and return a\n* {@link module:engine/view/documentselection~ViewDocumentSelection selection} instance containing these ranges. Ranges placed inside\n* {@link module:engine/view/text~ViewText text} nodes should be marked using `{` and `}` brackets:\n*\n* ```ts\n* const { text, selection } = _parseView( 'f{ooba}r' );\n* ```\n*\n* Ranges placed outside text nodes should be marked using `[` and `]` brackets:\n*\n* ```ts\n* const { root, selection } = _parseView( '<p>[<b>foobar</b>]</p>' );\n* ```\n*\n* ** Note: **\n* It is possible to unify selection markers to `[` and `]` for both (inside and outside text)\n* by setting `sameSelectionCharacters=true` option. It is mainly used when the view _parseView option is used by model utilities.\n*\n* Sometimes there is a need for defining the order of ranges inside the created selection. This can be achieved by providing\n* the range order array as an additional parameter:\n*\n* ```ts\n* const { root, selection } = _parseView( '{fo}ob{ar}{ba}z', { order: [ 2, 3, 1 ] } );\n* ```\n*\n* In the example above, the first range (`{fo}`) will be added to the selection as the second one, the second range (`{ar}`) will be\n* added as the third and the third range (`{ba}`) will be added as the first one.\n*\n* If the selection's last range should be added as a backward one\n* (so the {@link module:engine/view/documentselection~ViewDocumentSelection#anchor selection anchor} is represented\n* by the `end` position and {@link module:engine/view/documentselection~ViewDocumentSelection#focus selection focus} is\n* represented by the `start` position), use the `lastRangeBackward` flag:\n*\n* ```ts\n* const { root, selection } = _parseView( `{foo}bar{baz}`, { lastRangeBackward: true } );\n* ```\n*\n* Some more examples and edge cases:\n*\n* ```ts\n* // Returns an empty document fragment.\n* _parseView( '' );\n*\n* // Returns an empty document fragment and a collapsed selection.\n* const { root, selection } = _parseView( '[]' );\n*\n* // Returns an element and a selection that is placed inside the document fragment containing that element.\n* const { root, selection } = _parseView( '[<a></a>]' );\n* ```\n*\n* @param data An HTML-like string to be parsed.\n* @param options.order An array with the order of parsed ranges added to the returned\n* {@link module:engine/view/documentselection~ViewDocumentSelection Selection} instance. Each element should represent the\n* desired position of each range in the selection instance. For example: `[2, 3, 1]` means that the first range will be\n* placed as the second, the second as the third and the third as the first.\n* @param options.lastRangeBackward If set to `true`, the last range will be added as backward to the returned\n* {@link module:engine/view/documentselection~ViewDocumentSelection selection} instance.\n* @param options.rootElement The default root to use when parsing elements.\n* When set to `null`, the root element will be created automatically. If set to\n* {@link module:engine/view/element~ViewElement Element} or\n* {@link module:engine/view/documentfragment~ViewDocumentFragment DocumentFragment},\n* this node will be used as the root for all parsed nodes.\n* @param options.sameSelectionCharacters When set to `false`, the selection inside the text should be marked using\n* `{` and `}` and the selection outside the ext using `[` and `]`. When set to `true`, both should be marked with `[` and `]` only.\n* @returns Returns the parsed view node or an object with two fields: `view` and `selection` when selection ranges were included in the\n* data to parse.\n*/\nfunction _parseView(data, options = {}) {\n\tconst viewDocument = new ViewDocument(new StylesProcessor());\n\toptions.order = options.order || [];\n\tconst rangeParser = new RangeParser({ sameSelectionCharacters: options.sameSelectionCharacters });\n\tconst processor = new XmlDataProcessor(viewDocument, { namespaces: Object.keys(allowedTypes) });\n\tif (options.inlineObjectElements) processor.domConverter.inlineObjectElements.push(...options.inlineObjectElements);\n\tlet view = processor.toView(data);\n\tview = _convertViewElements(view);\n\tif (options.rootElement) {\n\t\tconst root = options.rootElement;\n\t\tconst nodes = view._removeChildren(0, view.childCount);\n\t\troot._removeChildren(0, root.childCount);\n\t\troot._appendChild(nodes);\n\t\tview = root;\n\t}\n\tconst ranges = rangeParser._parseView(view, options.order);\n\tif (view.is(\"documentFragment\") && view.childCount === 1) view = view.getChild(0);\n\tif (ranges.length) {\n\t\tconst selection = new ViewDocumentSelection(ranges, { backward: !!options.lastRangeBackward });\n\t\treturn {\n\t\t\tview,\n\t\t\tselection\n\t\t};\n\t}\n\tif (view.parent) view._remove();\n\treturn view;\n}\n/**\n* Private helper class used for converting ranges represented as text inside view {@link module:engine/view/text~ViewText text nodes}.\n*/\nvar RangeParser = class {\n\tsameSelectionCharacters;\n\t_positions;\n\t/**\n\t* Creates a range parser instance.\n\t*\n\t* @param options The range parser configuration.\n\t* @param options.sameSelectionCharacters When set to `true`, the selection inside the text is marked as\n\t* `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both are marked as `[` and `]`.\n\t*/\n\tconstructor(options) {\n\t\tthis.sameSelectionCharacters = !!options.sameSelectionCharacters;\n\t}\n\t/**\n\t* Parses the view and returns ranges represented inside {@link module:engine/view/text~ViewText text nodes}.\n\t* The method will remove all occurrences of `{`, `}`, `[` and `]` from found text nodes. If a text node is empty after\n\t* the process, it will be removed, too.\n\t*\n\t* @param node The starting node.\n\t* @param order The order of ranges. Each element should represent the desired position of the range after\n\t* sorting. For example: `[2, 3, 1]` means that the first range will be placed as the second, the second as the third and the third\n\t* as the first.\n\t* @returns An array with ranges found.\n\t*/\n\t_parseView(node, order) {\n\t\tthis._positions = [];\n\t\tthis._getPositions(node);\n\t\tlet ranges = this._createRanges();\n\t\tif (order.length) {\n\t\t\tif (order.length != ranges.length) throw new Error(`Parse error - there are ${ranges.length} ranges found, but ranges order array contains ${order.length} elements.`);\n\t\t\tranges = this._sortRanges(ranges, order);\n\t\t}\n\t\treturn ranges;\n\t}\n\t/**\n\t* Gathers positions of brackets inside the view tree starting from the provided node. The method will remove all occurrences of\n\t* `{`, `}`, `[` and `]` from found text nodes. If a text node is empty after the process, it will be removed, too.\n\t*\n\t* @param node Staring node.\n\t*/\n\t_getPositions(node) {\n\t\tif (node.is(\"documentFragment\") || node.is(\"element\")) {\n\t\t\tconst children = [...node.getChildren()];\n\t\t\tfor (const child of children) this._getPositions(child);\n\t\t}\n\t\tif (node.is(\"$text\")) {\n\t\t\tconst regexp = new RegExp(`[${TEXT_RANGE_START_TOKEN}${TEXT_RANGE_END_TOKEN}\\\\${ELEMENT_RANGE_END_TOKEN}\\\\${ELEMENT_RANGE_START_TOKEN}]`, \"g\");\n\t\t\tlet text = node.data;\n\t\t\tlet match;\n\t\t\tlet offset = 0;\n\t\t\tconst brackets = [];\n\t\t\twhile (match = regexp.exec(text)) {\n\t\t\t\tconst index = match.index;\n\t\t\t\tconst bracket = match[0];\n\t\t\t\tbrackets.push({\n\t\t\t\t\tbracket,\n\t\t\t\t\ttextOffset: index - offset\n\t\t\t\t});\n\t\t\t\toffset++;\n\t\t\t}\n\t\t\ttext = text.replace(regexp, \"\");\n\t\t\tnode._data = text;\n\t\t\tconst index = node.index;\n\t\t\tconst parent = node.parent;\n\t\t\tif (!text) node._remove();\n\t\t\tfor (const item of brackets) if (text) if (this.sameSelectionCharacters || !this.sameSelectionCharacters && (item.bracket == TEXT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_END_TOKEN)) this._positions.push({\n\t\t\t\tbracket: item.bracket,\n\t\t\t\tposition: new ViewPosition(node, item.textOffset)\n\t\t\t});\n\t\t\telse {\n\t\t\t\tif (!this.sameSelectionCharacters && item.textOffset !== 0 && item.textOffset !== text.length) throw new Error(`Parse error - range delimiter '${item.bracket}' is placed inside text node.`);\n\t\t\t\tconst offset = item.textOffset === 0 ? index : index + 1;\n\t\t\t\tthis._positions.push({\n\t\t\t\t\tbracket: item.bracket,\n\t\t\t\t\tposition: new ViewPosition(parent, offset)\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (!this.sameSelectionCharacters && item.bracket == TEXT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_END_TOKEN) throw new Error(`Parse error - text range delimiter '${item.bracket}' is placed inside empty text node. `);\n\t\t\t\tthis._positions.push({\n\t\t\t\t\tbracket: item.bracket,\n\t\t\t\t\tposition: new ViewPosition(parent, index)\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* Sorts ranges in a given order. Range order should be an array and each element should represent the desired position\n\t* of the range after sorting.\n\t* For example: `[2, 3, 1]` means that the first range will be placed as the second, the second as the third and the third\n\t* as the first.\n\t*\n\t* @param ranges Ranges to sort.\n\t* @param rangesOrder An array with new range order.\n\t* @returns Sorted ranges array.\n\t*/\n\t_sortRanges(ranges, rangesOrder) {\n\t\tconst sortedRanges = [];\n\t\tlet index = 0;\n\t\tfor (const newPosition of rangesOrder) {\n\t\t\tif (ranges[newPosition - 1] === void 0) throw new Error(\"Parse error - provided ranges order is invalid.\");\n\t\t\tsortedRanges[newPosition - 1] = ranges[index];\n\t\t\tindex++;\n\t\t}\n\t\treturn sortedRanges;\n\t}\n\t/**\n\t* Uses all found bracket positions to create ranges from them.\n\t*/\n\t_createRanges() {\n\t\tconst ranges = [];\n\t\tlet range = null;\n\t\tfor (const item of this._positions) {\n\t\t\tif (!range && (item.bracket == ELEMENT_RANGE_END_TOKEN || item.bracket == TEXT_RANGE_END_TOKEN)) throw new Error(`Parse error - end of range was found '${item.bracket}' but range was not started before.`);\n\t\t\tif (range && (item.bracket == ELEMENT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_START_TOKEN)) throw new Error(`Parse error - start of range was found '${item.bracket}' but one range is already started.`);\n\t\t\tif (item.bracket == ELEMENT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_START_TOKEN) range = new ViewRange(item.position, item.position);\n\t\t\telse {\n\t\t\t\trange.end = item.position;\n\t\t\t\tranges.push(range);\n\t\t\t\trange = null;\n\t\t\t}\n\t\t}\n\t\tif (range !== null) throw new Error(\"Parse error - range was started but no end delimiter was found.\");\n\t\treturn ranges;\n\t}\n};\n/**\n* Private helper class used for converting the view tree to a string.\n*/\nvar ViewStringify = class {\n\troot;\n\tselection;\n\tranges;\n\tshowType;\n\tshowPriority;\n\tshowAttributeElementId;\n\tignoreRoot;\n\tsameSelectionCharacters;\n\trenderUIElements;\n\trenderRawElements;\n\tdomConverter;\n\tskipListItemIds;\n\t/**\n\t* Creates a view stringify instance.\n\t*\n\t* @param selection A selection whose ranges should also be converted to a string.\n\t* @param options An options object.\n\t* @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n\t* instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n\t* @param options.showPriority When set to `true`, the attribute element's priority will be printed.\n\t* @param options.ignoreRoot When set to `true`, the root's element opening and closing tag will not\n\t* be outputted.\n\t* @param options.sameSelectionCharacters When set to `true`, the selection inside the text is marked as\n\t* `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both are marked as `[` and `]`.\n\t* @param options.renderUIElements When set to `true`, the inner content of each\n\t* {@link module:engine/view/uielement~ViewUIElement} will be printed.\n\t* @param options.renderRawElements When set to `true`, the inner content of each\n\t* @param options.domConverter When set to an actual {@link module:engine/view/domconverter~ViewDomConverter ViewDomConverter}\n\t* instance, it lets the conversion go through exactly the same flow the editing view is going through,\n\t* i.e. with view data filtering. Otherwise the simple stub is used.\n\t* {@link module:engine/view/rawelement~ViewRawElement} will be printed.\n\t* @param options.skipListItemIds When set to `true`, `<li>` elements will not have `listItemId` attribute. By default it's hidden\n\t* because it's randomly generated and hard to verify properly, while bringing little value.\n\t*/\n\tconstructor(root, selection, options) {\n\t\tthis.root = root;\n\t\tthis.selection = selection;\n\t\tthis.ranges = [];\n\t\tif (selection) this.ranges = [...selection.getRanges()];\n\t\tthis.showType = !!options.showType;\n\t\tthis.showPriority = !!options.showPriority;\n\t\tthis.showAttributeElementId = !!options.showAttributeElementId;\n\t\tthis.ignoreRoot = !!options.ignoreRoot;\n\t\tthis.sameSelectionCharacters = !!options.sameSelectionCharacters;\n\t\tthis.renderUIElements = !!options.renderUIElements;\n\t\tthis.renderRawElements = !!options.renderRawElements;\n\t\tthis.domConverter = options.domConverter || domConverterStub;\n\t\tthis.skipListItemIds = options.skipListItemIds !== void 0 ? !!options.skipListItemIds : true;\n\t}\n\t/**\n\t* Converts the view to a string.\n\t*\n\t* @returns String representation of the view elements.\n\t*/\n\tstringify() {\n\t\tlet result = \"\";\n\t\tthis._walkView(this.root, (chunk) => {\n\t\t\tresult += chunk;\n\t\t});\n\t\tif (this.skipListItemIds) result = result.replaceAll(/ data-list-item-id=\"[^\"]+\"/g, \"\");\n\t\treturn result;\n\t}\n\t/**\n\t* Executes a simple walker that iterates over all elements in the view tree starting from the root element.\n\t* Calls the `callback` with parsed chunks of string data.\n\t*/\n\t_walkView(root, callback) {\n\t\tconst ignore = this.ignoreRoot && this.root === root;\n\t\tif (root.is(\"element\") || root.is(\"documentFragment\")) {\n\t\t\tif (root.is(\"element\") && !ignore) callback(this._stringifyElementOpen(root));\n\t\t\tif (this.renderUIElements && root.is(\"uiElement\")) callback(root.render(document, this.domConverter).innerHTML);\n\t\t\telse if (this.renderRawElements && root.is(\"rawElement\")) {\n\t\t\t\tconst rawContentContainer = document.createElement(\"div\");\n\t\t\t\troot.render(rawContentContainer, this.domConverter);\n\t\t\t\tcallback(rawContentContainer.innerHTML);\n\t\t\t} else {\n\t\t\t\tlet offset = 0;\n\t\t\t\tcallback(this._stringifyElementRanges(root, offset));\n\t\t\t\tfor (const child of root.getChildren()) {\n\t\t\t\t\tthis._walkView(child, callback);\n\t\t\t\t\toffset++;\n\t\t\t\t\tcallback(this._stringifyElementRanges(root, offset));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (root.is(\"element\") && !ignore) callback(this._stringifyElementClose(root));\n\t\t}\n\t\tif (root.is(\"$text\")) callback(this._stringifyTextRanges(root));\n\t}\n\t/**\n\t* Checks if a given {@link module:engine/view/element~ViewElement element} has\n\t* a {@link module:engine/view/range~ViewRange#start range start}\n\t* or a {@link module:engine/view/range~ViewRange#start range end} placed at a given offset and returns its string representation.\n\t*/\n\t_stringifyElementRanges(element, offset) {\n\t\tlet start = \"\";\n\t\tlet end = \"\";\n\t\tlet collapsed = \"\";\n\t\tfor (const range of this.ranges) {\n\t\t\tif (range.start.parent == element && range.start.offset === offset) if (range.isCollapsed) collapsed += \"[]\";\n\t\t\telse start += ELEMENT_RANGE_START_TOKEN;\n\t\t\tif (range.end.parent === element && range.end.offset === offset && !range.isCollapsed) end += ELEMENT_RANGE_END_TOKEN;\n\t\t}\n\t\treturn end + collapsed + start;\n\t}\n\t/**\n\t* Checks if a given {@link module:engine/view/element~ViewElement Text node} has a\n\t* {@link module:engine/view/range~ViewRange#start range start} or a\n\t* {@link module:engine/view/range~ViewRange#start range end} placed somewhere inside. Returns a string representation of text\n\t* with range delimiters placed inside.\n\t*/\n\t_stringifyTextRanges(node) {\n\t\tconst length = node.data.length;\n\t\tconst data = node.data.split(\"\");\n\t\tlet rangeStartToken, rangeEndToken;\n\t\tif (this.sameSelectionCharacters) {\n\t\t\trangeStartToken = ELEMENT_RANGE_START_TOKEN;\n\t\t\trangeEndToken = ELEMENT_RANGE_END_TOKEN;\n\t\t} else {\n\t\t\trangeStartToken = TEXT_RANGE_START_TOKEN;\n\t\t\trangeEndToken = TEXT_RANGE_END_TOKEN;\n\t\t}\n\t\tdata[length] = \"\";\n\t\tconst result = data.map((letter) => {\n\t\t\treturn {\n\t\t\t\tletter,\n\t\t\t\tstart: \"\",\n\t\t\t\tend: \"\",\n\t\t\t\tcollapsed: \"\"\n\t\t\t};\n\t\t});\n\t\tfor (const range of this.ranges) {\n\t\t\tconst start = range.start;\n\t\t\tconst end = range.end;\n\t\t\tif (start.parent == node && start.offset >= 0 && start.offset <= length) if (range.isCollapsed) result[end.offset].collapsed += rangeStartToken + rangeEndToken;\n\t\t\telse result[start.offset].start += rangeStartToken;\n\t\t\tif (end.parent == node && end.offset >= 0 && end.offset <= length && !range.isCollapsed) result[end.offset].end += rangeEndToken;\n\t\t}\n\t\treturn result.map((item) => item.end + item.collapsed + item.start + item.letter).join(\"\");\n\t}\n\t/**\n\t* Converts the passed {@link module:engine/view/element~ViewElement element} to an opening tag.\n\t*\n\t* Depending on the current configuration, the opening tag can be simple (`<a>`), contain a type prefix (`<container:p>`,\n\t* `<attribute:a>` or `<empty:img>`), contain priority information ( `<attribute:a view-priority=\"20\">` ),\n\t* or contain element id ( `<attribute:span view-id=\"foo\">` ). Element attributes will also be included\n\t* (`<a href=\"https://ckeditor.com\" name=\"foobar\">`).\n\t*/\n\t_stringifyElementOpen(element) {\n\t\tconst priority = this._stringifyElementPriority(element);\n\t\tconst id = this._stringifyElementId(element);\n\t\treturn `<${[\n\t\t\t[this._stringifyElementType(element), element.name].filter((i) => i !== \"\").join(\":\"),\n\t\t\tpriority,\n\t\t\tid,\n\t\t\tthis._stringifyElementAttributes(element)\n\t\t].filter((i) => i !== \"\").join(\" \")}>`;\n\t}\n\t/**\n\t* Converts the passed {@link module:engine/view/element~ViewElement element} to a closing tag.\n\t* Depending on the current configuration, the closing tag can be simple (`</a>`) or contain a type prefix (`</container:p>`,\n\t* `</attribute:a>` or `</empty:img>`).\n\t*/\n\t_stringifyElementClose(element) {\n\t\treturn `</${[this._stringifyElementType(element), element.name].filter((i) => i !== \"\").join(\":\")}>`;\n\t}\n\t/**\n\t* Converts the passed {@link module:engine/view/element~ViewElement element's} type to its string representation\n\t*\n\t* Returns:\n\t* * 'attribute' for {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements},\n\t* * 'container' for {@link module:engine/view/containerelement~ViewContainerElement container elements},\n\t* * 'empty' for {@link module:engine/view/emptyelement~ViewEmptyElement empty elements},\n\t* * 'ui' for {@link module:engine/view/uielement~ViewUIElement UI elements},\n\t* * 'raw' for {@link module:engine/view/rawelement~ViewRawElement raw elements},\n\t* * an empty string when the current configuration is preventing showing elements' types.\n\t*/\n\t_stringifyElementType(element) {\n\t\tif (this.showType) {\n\t\t\tfor (const type in allowedTypes) if (element instanceof allowedTypes[type]) return type;\n\t\t}\n\t\treturn \"\";\n\t}\n\t/**\n\t* Converts the passed {@link module:engine/view/element~ViewElement element} to its priority representation.\n\t*\n\t* The priority string representation will be returned when the passed element is an instance of\n\t* {@link module:engine/view/attributeelement~ViewAttributeElement attribute element} and the current configuration allows to show the\n\t* priority. Otherwise returns an empty string.\n\t*/\n\t_stringifyElementPriority(element) {\n\t\tif (this.showPriority && element.is(\"attributeElement\")) return `view-priority=\"${element.priority}\"`;\n\t\treturn \"\";\n\t}\n\t/**\n\t* Converts the passed {@link module:engine/view/element~ViewElement element} to its id representation.\n\t*\n\t* The id string representation will be returned when the passed element is an instance of\n\t* {@link module:engine/view/attributeelement~ViewAttributeElement attribute element}, the element has an id\n\t* and the current configuration allows to show the id. Otherwise returns an empty string.\n\t*/\n\t_stringifyElementId(element) {\n\t\tif (this.showAttributeElementId && element.is(\"attributeElement\") && element.id) return `view-id=\"${element.id}\"`;\n\t\treturn \"\";\n\t}\n\t/**\n\t* Converts the passed {@link module:engine/view/element~ViewElement element} attributes to their string representation.\n\t* If an element has no attributes, an empty string is returned.\n\t*/\n\t_stringifyElementAttributes(element) {\n\t\tconst attributes = [];\n\t\tconst keys = [...element.getAttributeKeys()].sort();\n\t\tfor (const attribute of keys) {\n\t\t\tlet attributeValue;\n\t\t\tif (attribute === \"class\") attributeValue = [...element.getClassNames()].sort().join(\" \");\n\t\t\telse if (attribute === \"style\") attributeValue = [...element.getStyleNames()].sort().map((style) => `${style}:${element.getStyle(style).replace(/\"/g, \"&quot;\")}`).join(\";\");\n\t\t\telse attributeValue = element.getAttribute(attribute);\n\t\t\tattributes.push(`${attribute}=\"${attributeValue}\"`);\n\t\t}\n\t\treturn attributes.join(\" \");\n\t}\n};\n/**\n* Converts {@link module:engine/view/element~ViewElement elements} to\n* {@link module:engine/view/attributeelement~ViewAttributeElement attribute elements},\n* {@link module:engine/view/containerelement~ViewContainerElement container elements},\n* {@link module:engine/view/emptyelement~ViewEmptyElement empty elements} or\n* {@link module:engine/view/uielement~ViewUIElement UI elements}.\n* It converts the whole tree starting from the `rootNode`. The conversion is based on element names.\n* See the `_convertElement` method for more details.\n*\n* @param rootNode The root node to convert.\n* @returns The root node of converted elements.\n*/\nfunction _convertViewElements(rootNode) {\n\tif (rootNode.is(\"element\") || rootNode.is(\"documentFragment\")) {\n\t\tconst convertedElement = rootNode.is(\"documentFragment\") ? new ViewDocumentFragment(rootNode.document) : _convertElement(rootNode.document, rootNode);\n\t\tfor (const child of [...rootNode.getChildren()]) {\n\t\t\tif (convertedElement.is(\"emptyElement\")) throw new Error(\"Parse error - cannot parse inside ViewEmptyElement.\");\n\t\t\telse if (convertedElement.is(\"uiElement\")) throw new Error(\"Parse error - cannot parse inside UIElement.\");\n\t\t\telse if (convertedElement.is(\"rawElement\")) throw new Error(\"Parse error - cannot parse inside RawElement.\");\n\t\t\tconvertedElement._appendChild(_convertViewElements(child));\n\t\t}\n\t\treturn convertedElement;\n\t}\n\treturn rootNode;\n}\n/**\n* Converts an {@link module:engine/view/element~ViewElement element} to\n* {@link module:engine/view/attributeelement~ViewAttributeElement attribute element},\n* {@link module:engine/view/containerelement~ViewContainerElement container element},\n* {@link module:engine/view/emptyelement~ViewEmptyElement empty element} or\n* {@link module:engine/view/uielement~ViewUIElement UI element}.\n* If the element's name is in the format of `attribute:b`, it will be converted to\n* an {@link module:engine/view/attributeelement~ViewAttributeElement attribute element} with a priority of 11.\n* Additionally, attribute elements may have specified priority (for example `view-priority=\"11\"`) and/or\n* id (for example `view-id=\"foo\"`).\n* If the element's name is in the format of `container:p`, it will be converted to\n* a {@link module:engine/view/containerelement~ViewContainerElement container element}.\n* If the element's name is in the format of `empty:img`, it will be converted to\n* an {@link module:engine/view/emptyelement~ViewEmptyElement empty element}.\n* If the element's name is in the format of `ui:span`, it will be converted to\n* a {@link module:engine/view/uielement~ViewUIElement UI element}.\n* If the element's name does not contain any additional information, a {@link module:engine/view/element~ViewElement view Element} will be\n* returned.\n*\n* @param viewElement A view element to convert.\n* @returns A tree view element converted according to its name.\n*/\nfunction _convertElement(viewDocument, viewElement) {\n\tconst info = _convertElementNameAndInfo(viewElement);\n\tconst ElementConstructor = allowedTypes[info.type];\n\tconst newElement = ElementConstructor ? new ElementConstructor(viewDocument, info.name) : new ViewElement(viewDocument, info.name);\n\tif (newElement.is(\"attributeElement\")) {\n\t\tif (info.priority !== null) newElement._priority = info.priority;\n\t\tif (info.id !== null) newElement._id = info.id;\n\t}\n\tfor (const attributeKey of viewElement.getAttributeKeys()) newElement._setAttribute(attributeKey, viewElement.getAttribute(attributeKey));\n\treturn newElement;\n}\n/**\n* Converts the `view-priority` attribute and the {@link module:engine/view/element~ViewElement#name element's name} information needed for\n* creating {@link module:engine/view/attributeelement~ViewAttributeElement attribute element},\n* {@link module:engine/view/containerelement~ViewContainerElement container element},\n* {@link module:engine/view/emptyelement~ViewEmptyElement empty element} or\n* {@link module:engine/view/uielement~ViewUIElement UI element}.\n* The name can be provided in two formats: as a simple element's name (`div`), or as a type and name (`container:div`,\n* `attribute:span`, `empty:img`, `ui:span`);\n*\n* @param viewElement The element whose name should be converted.\n* @returns An object with parsed information:\n* * `name` The parsed name of the element.\n* * `type` The parsed type of the element. It can be `attribute`, `container` or `empty`.\n* * `priority` The parsed priority of the element.\n*/\nfunction _convertElementNameAndInfo(viewElement) {\n\tconst parts = viewElement.name.split(\":\");\n\tconst priority = _convertPriority(viewElement.getAttribute(\"view-priority\"));\n\tconst id = viewElement.hasAttribute(\"view-id\") ? viewElement.getAttribute(\"view-id\") : null;\n\tviewElement._removeAttribute(\"view-priority\");\n\tviewElement._removeAttribute(\"view-id\");\n\tif (parts.length == 1) return {\n\t\tname: parts[0],\n\t\ttype: priority !== null ? \"attribute\" : null,\n\t\tpriority,\n\t\tid\n\t};\n\tconst type = _convertType(parts[0]);\n\tif (type) return {\n\t\tname: parts[1],\n\t\ttype,\n\t\tpriority,\n\t\tid\n\t};\n\tthrow new Error(`Parse error - cannot parse element's name: ${viewElement.name}.`);\n}\n/**\n* Checks if the element's type is allowed. Returns `attribute`, `container`, `empty` or `null`.\n*/\nfunction _convertType(type) {\n\treturn type in allowedTypes ? type : null;\n}\n/**\n* Checks if a given priority is allowed. Returns null if the priority cannot be converted.\n*/\nfunction _convertPriority(priorityString) {\n\tconst priority = parseInt(priorityString, 10);\n\tif (!isNaN(priority)) return priority;\n\treturn null;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/dev-utils/model\n*/\n/**\n* Collection of methods for manipulating the {@link module:engine/model/model model} for testing purposes.\n*/\n/**\n* Writes the content of a model {@link module:engine/model/document~ModelDocument document} to an HTML-like string.\n*\n* ```ts\n* getData( editor.model ); // -> '<paragraph>Foo![]</paragraph>'\n* ```\n*\n* **Note:** A {@link module:engine/model/text~ModelText text} node that contains attributes will be represented as:\n*\n* ```xml\n* <$text attribute=\"value\">Text data</$text>\n* ```\n*\n* **Note:** Using this tool in production-grade code is not recommended. It was designed for development, prototyping,\n* debugging and testing.\n*\n* @param options.withoutSelection Whether to write the selection. When set to `true`, the selection will\n* not be included in the returned string.\n* @param options.rootName The name of the root from which the data should be stringified. If not provided,\n* the default `main` name will be used.\n* @param options.convertMarkers Whether to include markers in the returned string.\n* @returns The stringified data.\n*/\nconst _getModelData = /* #__PURE__ */ (() => {\n\tconst getModelData = function(model, options = {}) {\n\t\tif (!(model instanceof Model)) throw new TypeError(\"Model needs to be an instance of module:engine/model/model~Model.\");\n\t\tconst rootName = options.rootName || \"main\";\n\t\tconst root = model.document.getRoot(rootName);\n\t\treturn getModelData._stringify(root, options.withoutSelection ? null : model.document.selection, options.convertMarkers ? model.markers : null);\n\t};\n\tgetModelData._stringify = _stringifyModel;\n\treturn getModelData;\n})();\n/**\n* Sets the content of a model {@link module:engine/model/document~ModelDocument document} provided as an HTML-like string.\n*\n* ```ts\n* setData( editor.model, '<paragraph>Foo![]</paragraph>' );\n* ```\n*\n* **Note:** Remember to register elements in the {@link module:engine/model/model~Model#schema model's schema} before\n* trying to use them.\n*\n* **Note:** To create a {@link module:engine/model/text~ModelText text} node that contains attributes use:\n*\n* ```xml\n* <$text attribute=\"value\">Text data</$text>\n* ```\n*\n* **Note:** Using this tool in production-grade code is not recommended. It was designed for development, prototyping,\n* debugging and testing.\n*\n* @param data HTML-like string to write into the document.\n* @param options.rootName Root name where parsed data will be stored. If not provided, the default `main`\n* name will be used.\n* @param options.selectionAttributes A list of attributes which will be passed to the selection.\n* @param options.lastRangeBackward If set to `true`, the last range will be added as backward.\n* @param options.batchType Batch type used for inserting elements. See {@link module:engine/model/batch~Batch#constructor}.\n*/\nconst _setModelData = /* #__PURE__ */ (() => {\n\tconst setModelData = function(model, data, options = {}) {\n\t\tif (!(model instanceof Model)) throw new TypeError(\"Model needs to be an instance of module:engine/model/model~Model.\");\n\t\tlet modelDocumentFragment;\n\t\tlet selection = null;\n\t\tconst modelRoot = model.document.getRoot(options.rootName || \"main\");\n\t\tconst parsedResult = setModelData._parse(data, model.schema, {\n\t\t\tlastRangeBackward: options.lastRangeBackward,\n\t\t\tselectionAttributes: options.selectionAttributes,\n\t\t\tcontext: [modelRoot.name],\n\t\t\tinlineObjectElements: options.inlineObjectElements\n\t\t});\n\t\tif (\"model\" in parsedResult) {\n\t\t\tmodelDocumentFragment = parsedResult.model;\n\t\t\tselection = parsedResult.selection;\n\t\t} else modelDocumentFragment = parsedResult;\n\t\tif (options.batchType !== void 0) model.enqueueChange(options.batchType, writeToModel);\n\t\telse model.change(writeToModel);\n\t\tfunction writeToModel(writer) {\n\t\t\twriter.remove(writer.createRangeIn(modelRoot));\n\t\t\twriter.insert(modelDocumentFragment, modelRoot);\n\t\t\twriter.setSelection(null);\n\t\t\twriter.removeSelectionAttribute(model.document.selection.getAttributeKeys());\n\t\t\tif (selection) {\n\t\t\t\tconst ranges = [];\n\t\t\t\tfor (const range of selection.getRanges()) {\n\t\t\t\t\tconst start = new ModelPosition(modelRoot, range.start.path);\n\t\t\t\t\tconst end = new ModelPosition(modelRoot, range.end.path);\n\t\t\t\t\tranges.push(new ModelRange(start, end));\n\t\t\t\t}\n\t\t\t\twriter.setSelection(ranges, { backward: selection.isBackward });\n\t\t\t\tif (options.selectionAttributes) writer.setSelectionAttribute(selection.getAttributes());\n\t\t\t}\n\t\t}\n\t};\n\tsetModelData._parse = _parseModel;\n\treturn setModelData;\n})();\n/**\n* Converts model nodes to HTML-like string representation.\n*\n* **Note:** A {@link module:engine/model/text~ModelText text} node that contains attributes will be represented as:\n*\n* ```xml\n* <$text attribute=\"value\">Text data</$text>\n* ```\n*\n* @param node A node to stringify.\n* @param selectionOrPositionOrRange A selection instance whose ranges will be included in the returned string data.\n* If a range instance is provided, it will be converted to a selection containing this range. If a position instance\n* is provided, it will be converted to a selection containing one range collapsed at this position.\n* @param markers Markers to include.\n* @returns An HTML-like string representing the model.\n*/\nfunction _stringifyModel(node, selectionOrPositionOrRange = null, markers = null) {\n\tconst model = new Model();\n\tconst mapper = new Mapper();\n\tlet selection = null;\n\tlet range;\n\tif (node instanceof ModelRootElement || node instanceof ModelDocumentFragment) range = model.createRangeIn(node);\n\telse if (!node.parent) {\n\t\tconst fragment = new ModelDocumentFragment(node);\n\t\trange = model.createRangeIn(fragment);\n\t} else range = new ModelRange(model.createPositionBefore(node), model.createPositionAfter(node));\n\tif (selectionOrPositionOrRange instanceof ModelSelection) selection = selectionOrPositionOrRange;\n\telse if (selectionOrPositionOrRange instanceof ModelDocumentSelection) selection = selectionOrPositionOrRange;\n\telse if (selectionOrPositionOrRange instanceof ModelRange) selection = new ModelSelection(selectionOrPositionOrRange);\n\telse if (selectionOrPositionOrRange instanceof ModelPosition) selection = new ModelSelection(selectionOrPositionOrRange);\n\tconst stylesProcessor = new StylesProcessor();\n\tconst view = new EditingView(stylesProcessor);\n\tconst viewDocument = view.document;\n\tconst viewRoot = new ViewRootEditableElement(viewDocument, \"div\");\n\tviewRoot.rootName = \"main\";\n\tviewDocument.roots.add(viewRoot);\n\tconst downcastDispatcher = new DowncastDispatcher({\n\t\tmapper,\n\t\tschema: model.schema\n\t});\n\tmapper.bindElements(node.root, viewRoot);\n\tdowncastDispatcher.on(\"insert:$text\", insertText());\n\tdowncastDispatcher.on(\"insert\", insertAttributesAndChildren(), { priority: \"lowest\" });\n\tdowncastDispatcher.on(\"attribute\", (evt, data, conversionApi) => {\n\t\tif (data.item instanceof ModelSelection || data.item instanceof ModelDocumentSelection || data.item.is(\"$textProxy\")) wrap((modelAttributeValue, { writer }) => {\n\t\t\treturn writer.createAttributeElement(\"model-text-with-attributes\", { [data.attributeKey]: stringifyAttributeValue(modelAttributeValue) });\n\t\t})(evt, data, conversionApi);\n\t});\n\tdowncastDispatcher.on(\"insert\", insertElement((modelItem) => {\n\t\tconst attributes = convertAttributes(modelItem.getAttributes(), stringifyAttributeValue);\n\t\treturn new ViewContainerElement(viewDocument, modelItem.name, attributes);\n\t}));\n\tdowncastDispatcher.on(\"selection\", convertRangeSelection());\n\tdowncastDispatcher.on(\"selection\", convertCollapsedSelection());\n\tdowncastDispatcher.on(\"addMarker\", insertUIElement((data, { writer }) => {\n\t\tconst name = data.markerName + \":\" + (data.isOpening ? \"start\" : \"end\");\n\t\treturn writer.createUIElement(name);\n\t}));\n\tconst markersMap = /* @__PURE__ */ new Map();\n\tif (markers) for (const marker of Array.from(markers).sort((a, b) => a.name < b.name ? 1 : -1)) markersMap.set(marker.name, marker.getRange());\n\tconst writer = view._writer;\n\tdowncastDispatcher.convert(range, markersMap, writer);\n\tif (selection) downcastDispatcher.convertSelection(selection, markers || model.markers, writer);\n\tlet data = _stringifyView(viewRoot, viewDocument.selection, { sameSelectionCharacters: true });\n\tdata = data.substr(5, data.length - 11);\n\tview.destroy();\n\treturn data.replace(/* @__PURE__ */ new RegExp(\"model-text-with-attributes\", \"g\"), \"$text\");\n}\n/**\n* Parses an HTML-like string and returns the model {@link module:engine/model/rootelement~ModelRootElement rootElement}.\n*\n* **Note:** To create a {@link module:engine/model/text~ModelText text} node that contains attributes use:\n*\n* ```xml\n* <$text attribute=\"value\">Text data</$text>\n* ```\n*\n* **Note:** The default `options.context` value is `'$root'`, which only matches the generic root. When the editor\n* uses a custom root {@link module:core/editor/editorconfig~RootConfig#modelElement `modelElement`}, pass the target\n* {@link module:engine/model/rootelement~ModelRootElement root element} (or its configured model element name)\n* explicitly, otherwise the conversion result may be wrong.\n* See the {@glink framework/deep-dive/schema#custom-root-elements Custom root elements} section of the\n* {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n*\n* @param data HTML-like string to be parsed.\n* @param schema A schema instance used by converters for element validation.\n* @param options Additional configuration.\n* @param options.selectionAttributes A list of attributes which will be passed to the selection.\n* @param options.lastRangeBackward If set to `true`, the last range will be added as backward.\n* @param options.context The conversion context. If not provided, the default `'$root'` will be used.\n* @returns Returns the parsed model node or an object with two fields: `model` and `selection`,\n* when selection ranges were included in the data to parse.\n*/\nfunction _parseModel(data, schema, options = {}) {\n\tconst mapper = new Mapper();\n\tdata = data.replace(/* @__PURE__ */ new RegExp(\"\\\\$text\", \"g\"), \"model-text-with-attributes\");\n\tconst parsedResult = _parseView(data, {\n\t\tsameSelectionCharacters: true,\n\t\tlastRangeBackward: !!options.lastRangeBackward,\n\t\tinlineObjectElements: options.inlineObjectElements\n\t});\n\tlet viewDocumentFragment;\n\tlet viewSelection = null;\n\tlet selection = null;\n\tif (\"view\" in parsedResult && \"selection\" in parsedResult) {\n\t\tviewDocumentFragment = parsedResult.view;\n\t\tviewSelection = parsedResult.selection;\n\t} else viewDocumentFragment = parsedResult;\n\tconst modelController = new Model();\n\tconst upcastDispatcher = new UpcastDispatcher({ schema });\n\tupcastDispatcher.on(\"documentFragment\", convertToModelFragment$1(mapper));\n\tupcastDispatcher.on(\"element:model-text-with-attributes\", convertToModelText());\n\tupcastDispatcher.on(\"element\", convertToModelElement(mapper));\n\tupcastDispatcher.on(\"text\", convertToModelText());\n\tlet model = modelController.change((writer) => upcastDispatcher.convert(viewDocumentFragment.root, writer, options.context || \"$root\"));\n\tmapper.bindElements(model, viewDocumentFragment.root);\n\tif (model.childCount == 1) model = model.getChild(0);\n\tif (viewSelection) {\n\t\tconst ranges = [];\n\t\tfor (const viewRange of viewSelection.getRanges()) ranges.push(mapper.toModelRange(viewRange));\n\t\tselection = new ModelSelection(ranges, { backward: viewSelection.isBackward });\n\t\tfor (const [key, value] of toMap(options.selectionAttributes || [])) selection.setAttribute(key, value);\n\t}\n\tif (selection) return {\n\t\tmodel,\n\t\tselection\n\t};\n\treturn model;\n}\nfunction convertToModelFragment$1(mapper) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst childrenResult = conversionApi.convertChildren(data.viewItem, data.modelCursor);\n\t\tmapper.bindElements(data.modelCursor.parent, data.viewItem);\n\t\tObject.assign(data, childrenResult);\n\t\tevt.stop();\n\t};\n}\nfunction convertToModelElement(mapper) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst elementName = data.viewItem.name;\n\t\tif (!conversionApi.schema.checkChild(data.modelCursor, elementName)) throw new Error(`Element '${elementName}' was not allowed in given position.`);\n\t\tconst attributes = convertAttributes(data.viewItem.getAttributes(), parseAttributeValue);\n\t\tconst element = conversionApi.writer.createElement(data.viewItem.name, attributes);\n\t\tconversionApi.writer.insert(element, data.modelCursor);\n\t\tmapper.bindElements(element, data.viewItem);\n\t\tconversionApi.convertChildren(data.viewItem, element);\n\t\tdata.modelRange = ModelRange._createOn(element);\n\t\tdata.modelCursor = data.modelRange.end;\n\t\tevt.stop();\n\t};\n}\nfunction convertToModelText() {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!conversionApi.schema.checkChild(data.modelCursor, \"$text\")) throw new Error(\"Text was not allowed in given position.\");\n\t\tlet node;\n\t\tif (data.viewItem.is(\"element\")) {\n\t\t\tconst attributes = convertAttributes(data.viewItem.getAttributes(), parseAttributeValue);\n\t\t\tconst viewText = data.viewItem.getChild(0);\n\t\t\tnode = conversionApi.writer.createText(viewText.data, attributes);\n\t\t} else node = conversionApi.writer.createText(data.viewItem.data);\n\t\tconversionApi.writer.insert(node, data.modelCursor);\n\t\tdata.modelRange = ModelRange._createFromPositionAndShift(data.modelCursor, node.offsetSize);\n\t\tdata.modelCursor = data.modelRange.end;\n\t\tevt.stop();\n\t};\n}\nfunction parseAttributeValue(attribute) {\n\ttry {\n\t\treturn JSON.parse(attribute);\n\t} catch {\n\t\treturn attribute;\n\t}\n}\nfunction stringifyAttributeValue(data) {\n\tif (isPlainObject(data)) return JSON.stringify(data);\n\treturn data;\n}\nfunction* convertAttributes(attributes, converter) {\n\tfor (const [key, value] of attributes) yield [key, converter(value)];\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Note: This package is used only internally for debugging purposes and should not be used\n* in other environments. It uses a few special methods not existing in the default\n* building process. That is also why there are no tests for this file.\n*\n* @module engine/dev-utils/utils\n*/\n/**\n* Helper function, converts a map to the 'key1=\"value1\" key2=\"value1\"' format.\n*\n* @param map Map to convert.\n* @returns Converted map.\n* @internal\n*/\nfunction convertMapToTags(map) {\n\tlet string = \"\";\n\tfor (const entry of map) string += ` ${entry[0]}=${JSON.stringify(entry[1])}`;\n\treturn string;\n}\n/**\n* Helper function, converts a map to the `{\"key1\":\"value1\",\"key2\":\"value2\"}` format.\n*\n* @param map Map to convert.\n* @returns Converted map.\n* @internal\n*/\nfunction convertMapToStringifiedObject(map) {\n\tconst obj = {};\n\tfor (const entry of map) obj[entry[0]] = entry[1];\n\treturn JSON.stringify(obj);\n}\nconst treeDump = Symbol(\"_treeDump\");\nconst maxTreeDumpLength = 20;\n/**\n* Helper function that stores the `document` state for a given `version`.\n*\n* @internal\n*/\nfunction dumpTrees(document, version) {\n\tconsole.log(document, version);\n\tlet string = \"\";\n\tfor (const root of document.roots) string += root.printTree() + \"\\n\";\n\tdocument[treeDump][version] = string.substr(0, string.length - 1);\n\tconst overflow = document[treeDump].length - maxTreeDumpLength;\n\tif (overflow > 0) document[treeDump][overflow - 1] = null;\n}\n/**\n* Helper function that initializes document dumping.\n*\n* @internal\n*/\nfunction initDocumentDumping(document) {\n\tdocument[treeDump] = [];\n}\n/**\n* Helper function that logs document for the given version.\n*\n* @internal\n*/\nfunction logDocument(document, version) {\n\tconsole.log(\"--------------------\");\n\tif (document[treeDump][version]) console.log(document[treeDump][version]);\n\telse console.log(\"Tree log unavailable for given version: \" + version);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module engine/dev-utils/operationreplayer\n*/\n/**\n* Operation replayer is a development tool created for easy replaying of operations on the document from stringified operations.\n*\n* @internal\n*/\nvar OperationReplayer = class {\n\t_model;\n\t_logSeparator;\n\t_operationsToReplay;\n\t/**\n\t* @param model Data model.\n\t* @param logSeparator Separator between operations.\n\t* @param stringifiedOperations Operations to replay.\n\t*/\n\tconstructor(model, logSeparator, stringifiedOperations) {\n\t\tthis._model = model;\n\t\tthis._logSeparator = logSeparator;\n\t\tthis.setStringifiedOperations(stringifiedOperations);\n\t}\n\t/**\n\t* Parses the given string containing stringified operations and sets parsed operations as operations to replay.\n\t*\n\t* @param stringifiedOperations Stringified operations to replay.\n\t*/\n\tsetStringifiedOperations(stringifiedOperations) {\n\t\tif (stringifiedOperations === \"\") {\n\t\t\tthis._operationsToReplay = [];\n\t\t\treturn;\n\t\t}\n\t\tthis._operationsToReplay = stringifiedOperations.split(this._logSeparator).map((stringifiedOperation) => JSON.parse(stringifiedOperation));\n\t}\n\t/**\n\t* Returns operations to replay.\n\t*/\n\tgetOperationsToReplay() {\n\t\treturn this._operationsToReplay;\n\t}\n\t/**\n\t* Applies all operations with a delay between actions.\n\t*\n\t* @param timeInterval Time between applying operations.\n\t*/\n\tplay(timeInterval = 1e3) {\n\t\tconst operationReplayer = this;\n\t\treturn new Promise((res, rej) => {\n\t\t\tplay();\n\t\t\tfunction play() {\n\t\t\t\toperationReplayer.applyNextOperation().then((isFinished) => {\n\t\t\t\t\tif (isFinished) return res();\n\t\t\t\t\tsetTimeout(play, timeInterval);\n\t\t\t\t}).catch((err) => {\n\t\t\t\t\trej(err);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* Applies `numberOfOperations` operations, beginning after the last applied operation (or first, if no operations were applied).\n\t*\n\t* @param numberOfOperations The number of operations to apply.\n\t*/\n\tapplyOperations(numberOfOperations) {\n\t\tif (numberOfOperations <= 0) return;\n\t\treturn this.applyNextOperation().then((isFinished) => {\n\t\t\tif (!isFinished) return this.applyOperations(numberOfOperations - 1);\n\t\t});\n\t}\n\t/**\n\t* Applies all operations to replay at once.\n\t*/\n\tapplyAllOperations() {\n\t\treturn this.applyNextOperation().then((isFinished) => {\n\t\t\tif (!isFinished) return this.applyAllOperations();\n\t\t});\n\t}\n\t/**\n\t* Applies the next operation to replay. Returns a promise with the `isFinished` parameter that is `true` if the last\n\t* operation in the replayer has been applied, `false` otherwise.\n\t*/\n\tapplyNextOperation() {\n\t\tconst model = this._model;\n\t\treturn new Promise((res) => {\n\t\t\tmodel.enqueueChange((writer) => {\n\t\t\t\tconst operationJson = this._operationsToReplay.shift();\n\t\t\t\tif (!operationJson) return res(true);\n\t\t\t\tconst operation = OperationFactory.fromJSON(operationJson, model.document);\n\t\t\t\twriter.batch.addOperation(operation);\n\t\t\t\tmodel.applyOperation(operation);\n\t\t\t\tres(false);\n\t\t\t});\n\t\t});\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n\nexport { AttributeOperation, Batch, BubblingEmitterMixin, BubblingEventInfo, ClickObserver, CompositionObserver, Conversion, ConversionHelpers, DataController, Differ, DomEventObserver, DowncastDispatcher, DowncastHelpers, EditingController, EditingView, FakeSelectionObserver, FocusObserver, History, HtmlDataProcessor, InputObserver, InsertOperation, KeyObserver, Mapper, Marker, MarkerCollection, MarkerOperation, Matcher, MergeOperation, Model, ModelConsumable, ModelDocument, ModelDocumentFragment, ModelDocumentSelection, ModelElement, ModelLivePosition, ModelLiveRange, ModelNode, ModelNodeList, ModelPosition, ModelRange, ModelRootElement, ModelSchema, ModelSchemaContext, ModelSelection, ModelText, ModelTextProxy, ModelTreeWalker, ModelTypeCheckable, ModelWriter, MouseObserver, MoveOperation, MutationObserver, NoOperation, Observer, Operation, OperationFactory, PointerObserver, RenameOperation, RootAttributeOperation, RootOperation, SelectionObserver, SplitOperation, StylesMap, StylesProcessor, TabObserver, TouchObserver, UpcastDispatcher, UpcastHelpers, ViewUpcastWriter as UpcastWriter, ViewUpcastWriter, ViewAttributeElement, ViewConsumable, ViewContainerElement, ViewDataTransfer, ViewDocument, ViewDocumentDomEventData, ViewDocumentFragment, ViewDocumentSelection, ViewDomConverter, ViewDowncastWriter, ViewEditableElement, ViewElement, ViewEmptyElement, ViewNode, ViewPosition, ViewRange, ViewRawElement, ViewRenderer, ViewRootEditableElement, ViewSelection, ViewText, ViewTextProxy, ViewTokenList, ViewTreeWalker, ViewTypeCheckable, ViewUIElement, XmlDataProcessor, BasicHtmlWriter as _DataProcessorBasicHtmlWriter, DetachOperation as _DetachOperation, MapperCache as _MapperCache, OperationReplayer as _OperationReplayer, BR_FILLER as _VIEW_BR_FILLER, INLINE_FILLER as _VIEW_INLINE_FILLER, INLINE_FILLER_LENGTH as _VIEW_INLINE_FILLER_LENGTH, MARKED_NBSP_FILLER as _VIEW_MARKED_NBSP_FILLER, NBSP_FILLER as _VIEW_NBSP_FILLER, ViewElementConsumables as _ViewElementConversionConsumables, autoParagraphEmptyRoots as _autoParagraphEmptyModelRoots, convertMapToStringifiedObject as _convertMapToStringifiedObject, convertMapToTags as _convertMapToTags, deleteContent as _deleteModelContent, cleanSelection as _downcastCleanSelection, convertCollapsedSelection as _downcastConvertCollapsedSelection, convertRangeSelection as _downcastConvertRangeSelection, createViewElementFromDowncastHighlightDescriptor as _downcastCreateViewElementFromDowncastHighlightDescriptor, insertAttributesAndChildren as _downcastInsertAttributesAndChildren, insertElement as _downcastInsertElement, insertStructure as _downcastInsertStructure, insertText as _downcastInsertText, insertUIElement as _downcastInsertUIElement, remove as _downcastRemove, wrap as _downcastWrap, dumpTrees as _dumpTrees, getDataWithoutFiller as _getDataWithoutViewFiller, _getModelData, getNodeAfterPosition as _getModelNodeAfterPosition, getNodeBeforePosition as _getModelNodeBeforePosition, getTextNodeAtPosition as _getModelTextNodeAtPosition, getSelectedContent as _getSelectedModelContent, _getViewData, initDocumentDumping as _initDocumentDumping, injectSelectionPostFixer as _injectModelSelectionPostFixer, injectQuirksHandling as _injectViewQuirksHandling, injectUiElementHandling as _injectViewUIElementHandling, _insert as _insertIntoModelNodeList, insertContent as _insertModelContent, insertObject as _insertModelObject, isInlineFiller as _isInlineViewFiller, isParagraphable as _isParagraphableModelNode, isPatternMatched as _isViewPatternMatched, logDocument as _logDocument, mergeIntersectingRanges as _mergeIntersectingModelRanges, modifySelection as _modifyModelSelection, _move as _moveInModelNodeList, normalizeConsumables as _normalizeConversionConsumables, _normalizeNodes as _normalizeInModelNodeList, transform as _operationTransform, _parseModel, _parseView, _remove as _removeFromModelNodeList, _setAttribute as _setAttributeInModelNodeList, _setModelData, _setViewData, startsWithFiller as _startsWithViewFiller, _stringifyModel, _stringifyView, tryFixingRange as _tryFixingModelRange, convertSelectionChange as _upcastConvertSelectionChange, convertText as _upcastConvertText, convertToModelFragment as _upcastConvertToModelFragment, wrapInParagraph as _wrapInModelParagraph, addBackgroundStylesRules, addBorderStylesRules, addMarginStylesRules, addPaddingStylesRules, disableViewPlaceholder, enableViewPlaceholder, getBoxSidesStyleShorthandValue, getBoxSidesStyleValueReducer, getBoxSidesStyleValues, getPositionStyleShorthandNormalizer, getShorthandStylesValues, getViewFillerOffset, hideViewPlaceholder, isAttachmentStyleValue, isColorStyleValue, isLengthStyleValue, isLineStyleValue, isPercentageStyleValue, isPositionStyleValue, isRepeatStyleValue, isURLStyleValue, needsViewPlaceholder, showViewPlaceholder, transformOperationSets };\n//# sourceMappingURL=index.js.map"],"names":["documentPlaceholders","hasDisplayedPlaceholderDeprecationWarning","enableViewPlaceholder","view","element","text","isDirectHost","keepOnFocus","doc","writer","updateDocumentPlaceholders","evtInfo","evt","setPlaceholder","showViewPlaceholderTextDeprecationWarning","config","showViewPlaceholder","hideViewPlaceholder","needsViewPlaceholder","hasContent","selectionAnchor","child","placeholders","directHostElements","wasViewModified","updatePlaceholder","hostElement","getChildPlaceholderHostSubstitute","parent","firstChild","logWarning","ViewTypeCheckable","ViewNodeBase","EmitterMixin","ViewNode","document","__publicField","pos","CKEditorError","index","root","path","node","options","ancestors","ancestorsA","ancestorsB","i","thisPath","nodePath","result","compareArrays","type","data","json","ViewText","otherNode","ViewTextProxy","textNode","offsetInText","length","ViewConsumable","consumables","elementConsumables","ViewElementConsumables","normalizeConsumables","from","instance","name","token","attributeTokens","value","tokenValue","toConsume","attributes","normalizeConsumablePart","items","prefix","item","Matcher","pattern","singleElement","match","results","matchName","attributesMatch","matchAttributes","matchClasses","matchStyles","isPatternMatched","normalizePatterns","patterns","normalizedPatterns","key","excludeAttributes","StylesMap","styleProcessor","inlineStyle","parsedStyles","parseInlineStyles","propertyDescriptor","property","nameOrObject","valueOrObject","isObject","names","normalizedStylesToRemove","toArray","toPath","pathValue","get","appendStyleValue","removeStyles","arr","propertyName","expand","other","parsed","keys","clone","tokenPattern","valuePattern","styleName","relatedName","prop","StylesProcessor","propertyValue","styles","merge","extractor","normalizedValue","styleNamesKeysSet","style","callback","callbackOrPath","shorthandName","styleNames","alsoName","stylesString","quoteType","propertyNameStart","propertyValueStart","stylesMap","char","stylesObject","nameOrPath","valueToSet","set","toRemove","ViewTokenList","tokens","ViewElement","attrs","children","usesStylesMap","usesTokenList","otherElement","otherValue","className","array","iterator","matcher","classes","attributeName","deep","childrenClone","cloned","count","nodes","normalize$3","howMany","overwrite","currentValue","exclude","keyPattern","hasKey","hasValue","tokenMatch","tokenMatchItem","attrsMap","toMap","newValue","isIterable","normalizedNodes","elementName","ViewContainerElement","getViewFillerOffset","lastChild","ViewEditableElementBase","ObservableMixin","ViewEditableElement","isFocused","rootNameSymbol","ViewRootEditableElement","rootName","ViewTreeWalker","ViewPosition","skip","nextResult","prevPosition","position","previousPosition","textLength","textProxy","charactersCount","startOffset","offset","nextPosition","endOffset","editable","shift","shifted","treeWalker","otherPosition","otherPath","itemOrPosition","ViewRange","start","end","enlargeTrimSkip","nodeAfterStart","nodeBeforeEnd","otherRange","loose","containsStart","containsEnd","ranges","commonRangeStart","commonRangeEnd","startElement","endElement","size","ViewSelectionBase","ViewSelection","args","range","first","last","firstRange","lastRange","otherSelection","thisRange","found","numOfRangesA","rangeA","rangeB","selectable","placeOrOffset","ViewDocumentSelection","backward","newFocus","anchor","newRanges","isLastBackward","isBackward","storedRange","ViewDocumentSelectionBase","BubblingEventInfo","EventInfo","source","startRange","bubblingEmitterSymbol","callbackMapSymbol","contextsSymbol","BubblingEmitterMixin","base","Mixin","eventOrInfo","eventArgs","eventInfo","bubblingEmitter","getBubblingEmitter","customContexts","getCustomContexts","updateEventInfo","fireListenerFor","selectedElement","isCustomContext","hasMatchingCustomContext","getDeeperRangeParent","err","event","contexts","callbacksMap","getCallbackMap","context","wrappedCallback","wrapCallback","eventPhase","currentTarget","emitter","startParent","endParent","startPath","endPath","ViewDocumentBase","ViewDocument","stylesProcessor","Collection","postFixer","wasFixed","DEFAULT_PRIORITY","ViewAttributeElement","_a","getFillerOffset$3","nonUiChildrenCount","ViewEmptyElement","getFillerOffset$2","ViewUIElement","getFillerOffset$1","domDocument","domConverter","domElement","injectUiElementHandling","jumpOverUiElement","keyCodes","domSelection","domSelectionCollapsed","domParent","domOffset","viewPosition","jumpedOverAnyUiElement","nextViewPosition","newDomPosition","ViewRawElement","getFillerOffset","ViewDocumentFragmentBase","ViewDocumentFragment","normalize$2","ViewDowncastWriter","attributeElement","childrenOrOptions","isContainerOptions","containerElement","editableElement","emptyElement","renderFunction","uiElement","rawElement","elementOrOverwrite","elementOrTokens","isPlainObject","positionOrRange","newElement","sourceRange","targetPosition","positionOffset","positionParent","nodeBefore","nodeAfter","mergeTextNodes","prev","next","newPosition","validateNodesToInsert","nodeGroups","groups","lastGroup","breakAttributes","rangeOrItem","validateRangeContainer","breakStart","breakEnd","parentContainer","removed","mergePosition","walker","current","rangeToRemove","parentElement","ancestor","countBefore","attribute","_hasNonUiChildren","viewSelection","newRange","newName","viewElement","groupName","modeOrFilter","slotFactory","getParentContainer","insertionPosition","breakTextNode","endPosition","wrapElement","wrapPositions","isText","isAttribute","shouldABeOutsideB","newAttribute","offsetChange","unwrapElement","unwrapPositions","unwrapped","movePositionToTextNode","fakeElement","wrapRange","forceSplitText","rangeStart","rangeEnd","isContainerOrFragment","offsetAfter","clonedNode","nodesToMove","id","group","a","b","textToMove","t1","t2","nodeBeforeLength","validNodesToInsert","errorContext","validNode","startContainer","endContainer","NBSP_FILLER","MARKED_NBSP_FILLER","span","BR_FILLER","fillerBr","INLINE_FILLER","startsWithFiller","domNode","isInlineFiller","domText","getDataWithoutFiller","injectQuirksHandling","jumpOverInlineFiller","ViewRendererBase","ViewRenderer","selection","env","inlineFillerPosition","isInlineFillerRenderingPossible","fillerDomPosition","addInlineFiller","actualDomChildren","expectedDomChildren","diff","actions","areSimilarElements","counter","action","insertIndex","deleteIndex","viewChild","remove$1","firstPos","selectionPosition","domFillerNode","selectionParent","selectionOffset","isEditable","viewText","expectedText","filler","domAttr","previousDomNode","areTextNodes","nodesToUnbind","insertAt","filterOutFakeSelectionContainer","sameNodes$1","actualDom","expectedDom","comparator","newActions","actualSlice","expectedSlice","actualText","fastDiff","viewNode","domEditable","createFakeSelectionContainer","container","domRange","focus","fixGeckoSelectionAfterBr","oldViewSelection","activeDomElement","domParentOrArray","childNodes","nodeAfterFiller","fillerNode","node1","node2","isNode","isComment","actualDomChild","expectedDomChild","indexOf","childAtOffset","domChildList","fakeSelectionContainer","childList","BR_FILLER_REF","global","NBSP_FILLER_REF","MARKED_NBSP_FILLER_REF","UNSAFE_ATTRIBUTE_NAME_PREFIX","UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE","ViewDomConverter","blockFillerMode","renderingMode","viewDocumentSelection","domFragment","viewFragment","attributeKey","attributeValue","isImage","isMedia","html","fragment","bodyChildNodes","currentNode","_logUnsafeElement","textData","viewElementOrFragment","relatedViewElement","shouldRenderAttribute","isValidAttributeName","fillerPositionOffset","childView","transparentRendering","tempElement","viewRange","domStart","domEnd","viewParent","domBefore","domAfter","inlineNodes","generator","isViewBrFiller","domChild","isGeckoRestrictedDomSelection","viewRanges","viewStart","viewEnd","viewBefore","domElementOrDocumentFragment","previousSibling","nextSibling","documentFragmentOrElement","viewEditable","scrollX","scrollY","scrollPositions","forEachDomElementAncestor","scrollLeft","scrollTop","newViewSelection","isOnlyBrInBlock","isNbspBlockFiller","getAncestors","l","nestedInlineNodes","inlineNode","prevNodeEndsWithSpace","nodeEndsWithSpace","prevNode","nextNode","shouldLeftTrim","shouldRightTrim","isViewMarkedNbspFiller","isViewNbspFiller","isNextNodeInlineObjectElement","isNextNodeStartingWithSpace","nextStartsWithSpace","_hasViewParentOfType","getNext","viewName","originalDomElement","newDomElement","types","blockElements","hasBlockParent","ObserverBase","DomEmitterMixin","Observer","domTarget","ViewDocumentDomEventData","domEvent","additionalData","extend","DomEventObserver","eventType","KeyObserver","domEvt","getCode","FakeSelectionObserver","debounce","keyCode","newSelection","MutationObserver","domMutations","mutatedTextNodes","elementsWithMutatedChildren","mutation","mutations","viewChildren","newViewChildren","isEqualWith","sameNodes","addedNode","child1","child2","FocusObserver","selectedEditable","SelectionObserver","startDocumentIsSelecting","endDocumentIsSelecting","isSelectionWithinRootElements","CompositionObserver","ViewDataTransfer","nativeDataTransfer","getFiles","image","x","y","files","InputObserver","domTargetRanges","viewDocument","dataTransfer","targetRanges","isFollowedByInlineFiller","parts","partTargetRanges","dataPart","ArrowKeysObserver","isArrowKeyCode","TabObserver","EditingViewBase","EditingView","domRoot","viewRoot","initialDomRootAttributes","updateContenteditableAttribute","observer","ObserverConstructor","alignToTop","forceScroll","viewportOffset","ancestorOffset","originalArgs","cloneDeep","scrollViewportToShowTarget","callbackResult","flag","ModelTypeCheckable","ModelTextProxy","ModelTreeWalker","direction","ModelPosition","done","prevVisitedParent","textNodeAtPosition","getTextNodeAtPosition","getNodeAfterPosition","formatReturnValue","offsetInTextNode","getNodeBeforePosition","stickiness","newOffset","parentName","cmp","diffAt","commonLevel","level","checkTouchingBranch","checkOnlyZeroes","thisParentPath","posParentPath","operation","movedRange","isContained","deletePosition","transformed","insertPosition","sourcePosition","target","combined","left","right","checkOnlyMaxOffset","idx","add","ModelRange","startParentPath","endParentPath","shouldJoin","startPosition","posParent","operations","j","spread","newPos","moveRange","differenceSet","difference","common","transformedCommon","newStart","newEnd","ref","refIndex","MapperBase","MapperCacheBase","Mapper","MapperCache","viewContainer","viewBlock","modelParent","modelOffset","modelElement","markerName","elements","nameToElements","elementToNames","markerNames","modelRange","modelPosition","boundElements","viewElementName","lengthCallback","viewOffset","stack","len","cacheItem","startViewPosition","startModelOffset","targetModelOffset","useCache","traversedModelOffset","lastLength","cacheViewParent","cacheViewOffset","cache","newCacheItem","initialCacheItem","initialCache","lastValidNode","cacheListIndex","clearedItems","cacheList","ModelConsumable","_normalizeConsumableType","itemConsumables","test","eventGroup","canConsume","eventPrefix","symbol","startMap","endMap","compareMarkersForDowncast","name1","range1","name2","range2","DowncastDispatcherBase","DowncastDispatcher","conversionApi","differ","markers","refreshedItems","change","changes","entry","markerRange","markersToAdd","modelRoot","markersAtSelection","marker","shouldMarkerChangeBeConverted","walkerValueToEventData","oldValue","walkerValues","eventName","consumable","getEventName","itemKey","eventsFiredForConversion","eventsFiredForItem","mapper","ModelNode","attr","_deep","ModelSelectionBase","ModelSelection","anyNewRange","oldRange","visited","startBlock","getParentBlock$1","isStartBlockSelected","treewalker","block","isUnvisitedTopBlock","endBlock","isEndBlockSelected","limitStartPosition","limitEndPosition","isUnvisitedBlock","isTopBlockInRange","schema","hasParentLimit","parentBlock","findAncestorBlock","ModelLiveRangeBase","ModelLiveRange","model","boundModel","bindWithModel$1","isDetached","transform$2","deletionPosition","boundariesChanged","contentChanged","doesOperationChangeRangeContent","ModelText","storePrefix","ModelDocumentSelectionBase","ModelDocumentSelection","LiveSelection","prefixOrName","uid","batch","clearAttributesStoredInElement","attributeKeys","overrideUid","liveRange","changed","markerGroup","selectionRange","oldMarkers","hasMarker","contained","clearAll","newAttributes","oldAttributes","priority","newKey","oldKey","directChange","getTextAttributes","startNode","scan","siblingNodes","changeParent","storedAttributes","ModelNodeList","nodesArray","spliceArray","makeOffsetsArray","indexStart","lastNode","removedOffsetSum","offsets","ModelElement","relativePath","cloneNodes","normalize$1","clonedNodes","ConversionHelpers","dispatchers","conversionHelper","dispatcher","DowncastHelpers","downcastElementToElement","downcastElementToStructure","downcastAttributeToElement","downcastAttributeToAttribute","downcastMarkerToElement","downcastMarkerToHighlight","downcastMarkerToData","insertText","viewWriter","insertAttributesAndChildren","remove","modelEnd","removeRangeAndUnbind","createViewElementFromDowncastHighlightDescriptor","descriptor","convertRangeSelection","convertCollapsedSelection","brokenPosition","cleanSelection","wrap","elementCreator","oldViewElement","newViewElement","insertElement","consumer","defaultConsumer","removeElementAndUnbind","reinsertOrConvertNodes","insertStructure","slotsMap","createSlotFactory","validateSlotsChildren","fillSlots","insertUIElement","viewStartElement","viewEndElement","getBoundaryModelPosition","el","endViewPosition","existingName","existingStartPos","boundaryType","existingEndPos","removeUIElement","insertMarkerData","viewCreator","viewMarkerData","handleMarkerBoundary","isStart","elementAfter","elementBefore","isBefore","insertMarkerAsAttribute","insertMarkerAsElement","removeMarkerData","viewData","removeMarkerFromAttribute","changeAttribute","attributeCreator","oldAttribute","highlightText","highlightDescriptor","prepareDescriptor","rangeAfterWrap","highlightElement","removeHighlight","viewHighlightElement","normalizeModelElementConfig","normalizeToElementConfig","createConsumer","createChangeReducer","modelValue","getFromAttributeCreator","normalizeToAttributeConfig","viewElementType","modelData","createViewElementFromDefinition","viewElementDefinition","modelAttributeValue","createChangeReducerCallback","shouldReplace","reducedChanges","changeIndex","positionRelation","events","slot","childrenInSlots","uniqueChildrenInSlots","toViewPositionMapping","currentSlot","currentSlotNodes","modelNodes","modelChildNode","reinsertNode","modelNode","viewChildNode","preflight","autoParagraphEmptyRoots","isParagraphable","nodeOrType","wrapInParagraph","paragraph","UpcastHelpers","upcastElementToElement","upcastElementToAttribute","upcastAttributeToAttribute","upcastElementToMarker","upcastDataToMarker","convertToModelFragment","modelCursor","convertText","convertSelectionChange","modelSelection","converter","prepareToElementConverter","getViewElementNameFromConfig","normalizeModelAttributeConfig","prepareToAttributeConverter","viewKey","normalizeViewAttributeKeyValueConfig","normalizeElementToMarkerModelConfig","normalizedConfig","converterStart","normalizeDataToMarkerConfig","converterEnd","basePriority","priorities","maxPriority","priorityFactor","upcastAttributeToMarker","attrName","addMarkerElements","markerViewNames","markerViewName","viewConfig","matcherResult","getModelElement","input","normalized","viewAttributeKeyToCopy","defaultModelValue","shallow","onlyViewNameIsDefined","modelKey","setAttributeOn","viewItem","configToTest","modelAttribute","elementCreatorFunction","EditingControllerBase","EditingController","markerOrName","currentMarker","ModelSchemaBase","ModelSchema","ModelSchemaContext","itemName","definition","def","isAllowed","positionOrBaseElement","elementToMerge","checks","properties","selectionOrRangeOrPosition","rangeCommonAncestor","convertToMinimalFlatRanges","backwardWalker","forwardWalker","limitElement","combineWalkers","removeDisallowedAttributeFromNode","positionsInRange","attributeProperties","definitions","sourceRules","itemNames","compileBaseItemRule","propagateAllowIn","propagateAllowChildren","propagateDisallowIn","propagateDisallowChildren","resolveDisallows","compileAllowContentOf","compileAllowWhere","compileAllowAttributesOf","compileInheritPropertiesFrom","compileDefinitions","parentItem","parentItemDefinition","parentContext","genericChecks","childChecks","check","place","firstBlock","positionAfter","mapContextItem","ctx","query","sourceItemRules","itemRule","copyTypes","copyProperty","resolveInheritAll","childName","childItem","allowContentOfItemName","baseItem","allowWhereItemName","finalDefinitions","allowAttributeOfItemName","inheritPropertiesOfItemName","inheritFrom","typeNames","sourceItemRule","singleValue","ctxItem","forward","step","UpcastDispatcherBase","UpcastDispatcher","positionOrElement","createContextTree","documentFragment","extractMarkersFromModelFragment","elementOrModelCursor","nextModelCursor","splitResult","savedCursorParent","allowedParent","treeWalkerValue","originalPart","splitPart","cursorParent","list","modelItem","markerElements","markerElement","currentPosition","contextDefinition","BasicHtmlWriter","HtmlDataProcessor","DataControllerBase","DataController","trim","modelElementOrFragment","viewDocumentFragment","_getMarkersRelativeToElement","initialData","newData","rootNames","elementRange","isMarkerCollapsed","isMarkerAtElementBoundary","updatedMarkerRange","Conversion","downcastDispatchers","upcastDispatchers","alias","isDowncast","_getAllUpcastDefinitions","helpers","_getUpcastDefinition","upcastAlso","upcastAlsoItem","Operation","baseVersion","_insert","_normalizeNodes","sum","_splitNodeAtPosition","_mergeNodesAtIndex","_remove","_move","_setAttribute","convert","_haveSameAttributes","mergedNode","offsetDiff","firstPart","secondPart","nodeA","nodeB","iteratorA","iteratorB","MoveOperation","newTargetPosition","sourceElement","targetElement","sourceOffset","targetOffset","InsertOperation","insert","graveyard","gyPosition","originalNodes","SplitOperation","splitPosition","graveyardPosition","MergeOperation","splitElement","mergedElement","MarkerOperation","affectsData","AttributeOperation","isEqual","NoOperation","RenameOperation","oldName","RootAttributeOperation","RootOperation","isAdd","OperationFactory","transformations","setTransformation","OperationA","OperationB","transformationFunction","aGroup","getTransformation","noUpdateTransformation","transform","e","transformOperationSets","operationsA","operationsB","contextFactory","ContextFactory","originalOperations","nextTransformIndex","op","opA","indexB","opB","newOpsA","newOpsB","newOpA","handlePartialMarkerOperations","updateBaseVersions","useRelations","forceWeakRemove","takeFrom","originalOperation","wasInLeftElement","wasStartBeforeMergedElement","wasEndBeforeMergedElement","wasInRightElement","aIsStrong","originalOp","origB","undoneB","origA","relationsA","relation","markerOps","partialRanges","r","_getComplementaryAttributeOperations","insertOperation","insertValue","_breakRangeByMoveOperation","moveOp","diffs","aNewRange","aToGraveyard","bToGraveyard","removedRange","insertBefore","_moveTargetIntoMovedRange","_makeMoveOperationsFromRanges","aCompB","shouldSpread","rightRange","movesGraveyardElement","gyMoveSource","splitNodesMoveSource","aTarget","gyMoveTarget","gyMove","splitNodesMoveTargetPath","splitNodesMoveTarget","splitNodesMove","renamePath","splitPath","additionalSplit","rangeToMove","gyElementMoved","newParentPosition","newTargetPath","splitAtTarget","howManyRemoved","aInGraveyard","bInGraveyard","newPositionPath","ModelLivePositionBase","ModelLivePosition","bindWithModel","transform$1","oldPosition","Batch","isUndoable","isLocal","isUndo","isTyping","Differ","markerCollection","operationToBuffer","sourceParentInserted","targetParentInserted","markerData","graveyardParent","mergedIntoElement","oldMarkerData","newMarkerData","buffered","markerAdded","markerRemoved","markerChanged","diffSet","childrenBefore","childrenAfter","_getChildrenSnapshots","diffInstructions","_generateDiffInstructionsFromChanges","instruction","childSnapshotBefore","diffItem","beforeAttributes","afterAttributes","diffItems","prevIndex","prevDiff","thisDiff","isConsecutiveTextRemove","isConsecutiveTextAdd","isConsecutiveAttributeChange","v","_changesInGraveyardFilter","isAttached","attrEntry","changeItem","state","currentStatePriority","diffItemType","childrenSnapshots","snapshot","inc","old","incEnd","oldEnd","intersectionLength","howManyAfter","attributePart","elementSnapshot","elementSnapshotBefore","_getSingleNodeSnapshot","snapshots","oldChildrenLength","oldChildrenHandled","posInGy","rangeInGy","History","version","fromBaseVersion","toBaseVersion","firstOperation","inclusiveTo","gapFrom","gapTo","fromIndex","toIndex","operationIndex","undoneOperation","undoingOperation","ModelRootElement","graveyardName","ModelDocumentBase","ModelDocument","includeDetached","roots","defaultRoot","validateTextNodePosition","rangeBoundary","isInsideSurrogatePair","isInsideCombinedSymbol","MarkerCollectionBase","MarkerBase","MarkerCollection","Marker","managedUsingOperations","oldMarker","hasChanged","DetachOperation","ModelDocumentFragment","normalize","ModelWriter","isSameTree","rangeRootPosition","itemOrPositionOrOffset","itemOrRange","setAttributeOnRange","setAttributeOnItem","val","removeAttributesFromItem","flat","applyRemoveOperation","renameOperation","firstSplitElement","firstCopyElement","split","elementOrString","shiftedRange","usingOperation","applyMarkerOperation","hasUsingOperationDefined","affectsDataDefined","currentRange","updatedRange","rootOrName","keyOrObjectOrIterable","keyOrIterableOfKeys","storeKey","isAffected","affectedInLeftElement","affectedInRightElement","affectedAfterLeftElement","affectedBeforeRightElement","lastSplitPosition","valueBefore","valueAfter","addOperation","previousValue","rootA","rootB","injectSelectionPostFixer","selectionPostFixer","correctedRange","tryFixingRange","mergeIntersectingRanges","tryFixingCollapsedRange","tryFixingNonCollapsedRage","originalPosition","nearestSelectionRange","ancestorObject","fixedPosition","isTextAllowedOnStart","isTextAllowedOnEnd","startLimitElement","endLimitElement","checkSelectionOnNonLimitElements","fixedStart","fixedEnd","isStartInLimit","isEndInLimit","bothInSameParent","expandStart","isSelectable","expandEnd","findOutermostLimitAncestor","startingNode","isLimitNode","startIsOnBlock","endIsOnBlock","rangesToMerge","rangeIndexesToRemove","currentRangeIndex","previousRanges","previousRangeIndex","previousRange","mergedRange","_","deleteContent","selRange","documentSelection","selectionIsDocumentSelection","isRelatedToDocumentSelection","selectionAttributes","selectionParentWasEmpty","shouldEntireContentBeReplacedWithParagraph","replaceEntireContentWithParagraph","attributesForAutoparagraph","getLivePositionsForSelectedBlocks","mergeBranches","collapseSelectionAt","shouldAutoparagraph","insertParagraph","restoreSelectionAttributesOnEmptyParent","getParentBlock","newEndPosition","skippedRange","checkShouldMerge","startAncestor","endAncestor","getAncestorsJustBelowCommonAncestor","mergeBranchesRight","mergeBranchesLeft","commonAncestor","parentToRemove","mergeRight","isCrossingLimitElement","positionA","positionB","isTextAllowed","isParagraphAllowed","leftPos","rightPos","rangeToCheck","getSelectedContent","frag","commonPath","commonParent","flatSubtreeRange","leftExcessRange","removeRangeContent","parentsToCheck","itemRange","parentToCheck","removeRange","insertContent","content","insertion","Insertion","fakeMarkerElements","nodesToInsert","markersPosition","isCollapsed","posA","posB","collapsed","isAtBeginning","isAtEnd","selectionLiveRange","markersData","isStartBoundary","elementPosition","rangeOnInsertion","affectedRange","unwrap","itemParent","positionAfterLastNode","positionAfterNode","livePosition","mergePosLeft","mergePosRight","allowedIn","tempPos","contextElement","childNode","insertObject","object","originalSelection","insertionSelection","firstSelectedBlock","attributesToCopy","elementToInsert","insertionPositionParent","updateSelection","paragraphAttributes","nextElement","wordBoundaryCharacters","modifySelection","isForward","unit","treatEmojiAsSingleUnit","getSearchRange","tryExtendingTo","getCorrectWordBreakPosition","getCorrectPosition","isInsideEmojiSequence","isAtNodeBoundary","isAtWordBoundary","searchEnd","offsetToCheck","ModelBase","Model","methodName","canEditAt","batchOrType","rest","normalizeSelectable","subject","ignoreWhitespaces","ignoreMarkers","intersectingMarker","ret","currentBatch","callbackReturnValue","MouseObserver","PointerObserver"],"mappings":"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","x_google_ignoreList":[0]}