trilium/public/libraries/ckeditor/ckeditor.js.map
2017-12-02 10:37:12 -05:00

1 line
2.4 MiB
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 68c4dd51e9faa983488b","webpack:////workspace/ckeditor5/node_modules/css-loader/lib/css-base.js","webpack:////workspace/ckeditor5/node_modules/style-loader/lib/addStyles.js","webpack:///../ckeditor5-utils/src/lib/lodash/_root.js","webpack:///(webpack)/buildin/harmony-module.js","webpack:///../ckeditor5-utils/src/ckeditorerror.js","webpack:///../ckeditor5-utils/src/log.js","webpack:///../ckeditor5-utils/src/translation-service.js","webpack:///../ckeditor5-utils/src/locale.js","webpack:///../ckeditor5-utils/src/mix.js","webpack:///../ckeditor5-utils/src/spy.js","webpack:///../ckeditor5-utils/src/uid.js","webpack:///../ckeditor5-utils/src/priorities.js","webpack:///../ckeditor5-utils/src/emittermixin.js","webpack:///../ckeditor5-utils/src/lib/lodash/eq.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseKeysIn.js","webpack:///../ckeditor5-utils/src/observablemixin.js","webpack:///../ckeditor5-utils/src/objecttomap.js","webpack:///../ckeditor5-utils/src/tomap.js","webpack:///../ckeditor5-engine/src/model/node.js","webpack:///../ckeditor5-utils/src/isiterable.js","webpack:///../ckeditor5-engine/src/model/element.js","webpack:///../ckeditor5-engine/src/model/treewalker.js","webpack:///../ckeditor5-utils/src/lib/lodash/last.js","webpack:///../ckeditor5-utils/src/comparearrays.js","webpack:///../ckeditor5-engine/src/model/position.js","webpack:///../ckeditor5-utils/src/lib/lodash/_ListCache.js","webpack:///../ckeditor5-utils/src/lib/lodash/_Hash.js","webpack:///../ckeditor5-utils/src/lib/lodash/_MapCache.js","webpack:///../ckeditor5-utils/src/lib/lodash/_Stack.js","webpack:///../ckeditor5-utils/src/lib/lodash/_getSymbols.js","webpack:///../ckeditor5-utils/src/lib/lodash/_getTag.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseClone.js","webpack:///../ckeditor5-engine/src/view/matcher.js","webpack:///../ckeditor5-engine/src/view/element.js","webpack:///../ckeditor5-engine/src/view/textproxy.js","webpack:///../ckeditor5-engine/src/view/containerelement.js","webpack:///../ckeditor5-engine/src/view/editableelement.js","webpack:///../ckeditor5-engine/src/view/range.js","webpack:///../ckeditor5-engine/src/conversion/mapper.js","webpack:///../ckeditor5-engine/src/model/documentfragment.js","webpack:///../ckeditor5-engine/src/conversion/modelconversiondispatcher.js","webpack:///../ckeditor5-engine/src/view/attributeelement.js","webpack:///../ckeditor5-engine/src/view/emptyelement.js","webpack:///../ckeditor5-utils/src/env.js","webpack:///../ckeditor5-utils/src/keyboard.js","webpack:///../ckeditor5-engine/src/view/uielement.js","webpack:///../ckeditor5-engine/src/view/documentfragment.js","webpack:///../ckeditor5-engine/src/view/writer.js","webpack:///../ckeditor5-engine/src/conversion/model-to-view-converters.js","webpack:///../ckeditor5-engine/src/model/writer.js","webpack:///../ckeditor5-engine/src/conversion/viewconversiondispatcher.js","webpack:///../ckeditor5-engine/src/conversion/view-to-model-converters.js","webpack:///../ckeditor5-engine/src/model/liveposition.js","webpack:///../ckeditor5-engine/src/controller/insertcontent.js","webpack:///../ckeditor5-engine/src/controller/deletecontent.js","webpack:///../ckeditor5-utils/src/unicode.js","webpack:///../ckeditor5-engine/src/controller/modifyselection.js","webpack:///../ckeditor5-engine/src/controller/getselectedcontent.js","webpack:///../ckeditor5-engine/src/controller/datacontroller.js","webpack:///../ckeditor5-utils/src/lib/lodash/_SetCache.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseIsEqual.js","webpack:///../ckeditor5-engine/src/model/batch.js","webpack:///../ckeditor5-engine/src/model/delta/attributedelta.js","webpack:///../ckeditor5-engine/src/model/delta/movedelta.js","webpack:///../ckeditor5-engine/src/model/delta/removedelta.js","webpack:///../ckeditor5-engine/src/model/delta/renamedelta.js","webpack:///../ckeditor5-engine/src/model/operation/transform.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseSlice.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseFlatten.js","webpack:///../ckeditor5-utils/src/lib/lodash/memoize.js","webpack:///../ckeditor5-engine/src/model/delta/transform.js","webpack:///../ckeditor5-engine/src/model/delta/markerdelta.js","webpack:///../ckeditor5-engine/src/model/delta/basic-transformations.js","webpack:///../ckeditor5-engine/src/model/rootelement.js","webpack:///../ckeditor5-engine/src/model/liverange.js","webpack:///../ckeditor5-utils/src/mapsequal.js","webpack:///../ckeditor5-engine/src/model/selection.js","webpack:///../ckeditor5-engine/src/model/documentselection.js","webpack:///../ckeditor5-engine/src/model/schema.js","webpack:///../ckeditor5-engine/src/model/markercollection.js","webpack:///../ckeditor5-engine/src/model/document.js","webpack:///../ckeditor5-core/src/editor/editor.js","webpack:///../ckeditor5-utils/src/dom/isdomnode.js","webpack:///../ckeditor5-utils/src/dom/emittermixin.js","webpack:///../ckeditor5-utils/src/keystrokehandler.js","webpack:///../ckeditor5-utils/src/count.js","webpack:///../ckeditor5-engine/src/view/selection.js","webpack:///../ckeditor5-engine/src/view/filler.js","webpack:///../ckeditor5-utils/src/diff.js","webpack:///../ckeditor5-utils/src/dom/insertat.js","webpack:///../ckeditor5-utils/src/dom/remove.js","webpack:///../ckeditor5-engine/src/view/renderer.js","webpack:///../ckeditor5-utils/src/dom/global.js","webpack:///../ckeditor5-utils/src/dom/indexof.js","webpack:///../ckeditor5-utils/src/dom/getancestors.js","webpack:///../ckeditor5-utils/src/dom/getcommonancestor.js","webpack:///../ckeditor5-engine/src/view/domconverter.js","webpack:///../ckeditor5-engine/src/view/rooteditableelement.js","webpack:///../ckeditor5-engine/src/view/observer/fakeselectionobserver.js","webpack:///../ckeditor5-utils/src/dom/isrange.js","webpack:///../ckeditor5-utils/src/dom/iswindow.js","webpack:///../ckeditor5-utils/src/lib/lodash/isElement.js","webpack:///../ckeditor5-utils/src/dom/getborderwidths.js","webpack:///../ckeditor5-utils/src/dom/rect.js","webpack:///../ckeditor5-utils/src/dom/scroll.js","webpack:///../ckeditor5-engine/src/view/document.js","webpack:///../ckeditor5-engine/src/conversion/view-selection-to-model-converters.js","webpack:///../ckeditor5-engine/src/conversion/model-selection-to-view-converters.js","webpack:///../ckeditor5-engine/src/controller/editingcontroller.js","webpack:///../ckeditor5-utils/src/dom/getdatafromelement.js","webpack:///../ckeditor5-utils/src/dom/setdatainelement.js","webpack:///../ckeditor5-core/src/editor/standardeditor.js","webpack:///../ckeditor5-ui/src/viewcollection.js","webpack:///../ckeditor5-utils/src/lib/lodash/cloneDeepWith.js","webpack:///../ckeditor5-ui/src/template.js","webpack:///../ckeditor5-ui/src/view.js","webpack:///../ckeditor5-utils/src/dom/getpositionedancestor.js","webpack:///../ckeditor5-utils/src/dom/position.js","webpack:///../ckeditor5-utils/src/dom/tounit.js","webpack:///../ckeditor5-ui/src/panel/balloon/balloonpanelview.js","webpack:///../ckeditor5-utils/src/first.js","webpack:///../ckeditor5-ui/src/panel/balloon/contextualballoon.js","webpack:///../ckeditor5-ui/src/focuscycler.js","webpack:///../ckeditor5-ui/src/toolbar/toolbarseparatorview.js","webpack:///../ckeditor5-ui/src/bindings/preventdefault.js","webpack:///../ckeditor5-ui/src/toolbar/toolbarview.js","webpack:///../ckeditor5-ui/src/toolbar/normalizetoolbarconfig.js","webpack:///../ckeditor5-ui/src/toolbar/contextual/contextualtoolbar.js","webpack:///../ckeditor5-ui/src/componentfactory.js","webpack:///../ckeditor5-ui/src/toolbar/enabletoolbarkeyboardfocus.js","webpack:///../ckeditor5-editor-balloon/src/ballooneditorui.js","webpack:///../ckeditor5-clipboard/src/datatransfer.js","webpack:///../ckeditor5-clipboard/src/clipboardobserver.js","webpack:///../ckeditor5-clipboard/src/utils/plaintexttohtml.js","webpack:///../ckeditor5-clipboard/src/utils/normalizeclipboarddata.js","webpack:///../ckeditor5-clipboard/src/utils/viewtoplaintext.js","webpack:///../ckeditor5-clipboard/src/clipboard.js","webpack:///../ckeditor5-enter/src/entercommand.js","webpack:///../ckeditor5-enter/src/enterobserver.js","webpack:///../ckeditor5-utils/src/difftochanges.js","webpack:///../ckeditor5-typing/src/changebuffer.js","webpack:///../ckeditor5-typing/src/input.js","webpack:///../ckeditor5-typing/src/deletecommand.js","webpack:///../ckeditor5-undo/src/basecommand.js","webpack:///../ckeditor5-undo/src/undocommand.js","webpack:///../ckeditor5-adapter-ckfinder/src/utils.js","webpack:///../ckeditor5-adapter-ckfinder/src/uploadadapter.js","webpack:///../ckeditor5-autoformat/src/inlineautoformatengine.js","webpack:///../ckeditor5-autoformat/src/autoformat.js","webpack:///../ckeditor5-engine/src/conversion/buildmodelconverter.js","webpack:///../ckeditor5-engine/src/conversion/buildviewconverter.js","webpack:///../ckeditor5-basic-styles/src/attributecommand.js","webpack:///../ckeditor5-block-quote/src/blockquotecommand.js","webpack:///../ckeditor5-block-quote/src/blockquoteengine.js","webpack:////workspace/ckeditor5/node_modules/@ckeditor/ckeditor-cloudservices-core/src/uploadgateway/fileuploader.js","webpack:////workspace/ckeditor5/node_modules/@ckeditor/ckeditor-cloudservices-core/src/uploadgateway/uploadgateway.js","webpack:///../ckeditor5-image/src/image/converters.js","webpack:///../ckeditor5-widget/src/highlightstack.js","webpack:///../ckeditor5-widget/src/utils.js","webpack:///../ckeditor5-image/src/image/utils.js","webpack:///../ckeditor5-image/src/image/imageengine.js","webpack:///../ckeditor5-engine/src/view/observer/mouseobserver.js","webpack:///../ckeditor5-widget/src/widget.js","webpack:///../ckeditor5-image/src/imagetextalternative/imagetextalternativecommand.js","webpack:///../ckeditor5-ui/src/bindings/clickoutsidehandler.js","webpack:///../ckeditor5-ui/src/label/labelview.js","webpack:///../ckeditor5-ui/src/bindings/submithandler.js","webpack:///../ckeditor5-image/src/imagetextalternative/ui/textalternativeformview.js","webpack:///../ckeditor5-image/src/image/ui/utils.js","webpack:///../ckeditor5-upload/src/utils.js","webpack:///../ckeditor5-upload/src/imageuploadengine.js","webpack:///../ckeditor5-upload/src/ui/filedialogbuttonview.js","webpack:///../ckeditor5-upload/src/imageuploadprogress.js","webpack:///../ckeditor5-upload/src/imageupload.js","webpack:///../ckeditor5-paragraph/src/paragraphcommand.js","webpack:///../ckeditor5-paragraph/src/paragraph.js","webpack:///../ckeditor5-heading/src/headingcommand.js","webpack:///../ckeditor5-heading/src/headingengine.js","webpack:///../ckeditor5-ui/src/dropdown/createdropdown.js","webpack:///../ckeditor5-ui/src/dropdown/list/createlistdropdown.js","webpack:///../ckeditor5-heading/src/heading.js","webpack:///../ckeditor5-engine/src/view/placeholder.js","webpack:///../ckeditor5-image/src/imagecaption/utils.js","webpack:///../ckeditor5-image/src/imagecaption/imagecaptionengine.js","webpack:///../ckeditor5-image/src/imagestyle/converters.js","webpack:///../ckeditor5-image/src/imagestyle/imagestyleengine.js","webpack:///../ckeditor5-image/src/imagestyle.js","webpack:///../ckeditor5-link/src/findlinkrange.js","webpack:///../ckeditor5-link/src/linkcommand.js","webpack:///../ckeditor5-link/src/link.js","webpack:///../ckeditor5-list/src/listcommand.js","webpack:///../ckeditor5-list/src/indentcommand.js","webpack:///../ckeditor5-list/src/viewlistitemelement.js","webpack:///../ckeditor5-list/src/converters.js","webpack:///../ckeditor5-list/src/listengine.js","webpack:///../ckeditor5-utils/src/lib/lodash/rest.js","webpack:///../ckeditor5-utils/src/lib/lodash/_getPrototype.js","webpack:///../ckeditor5-utils/src/lib/lodash/_isHostObject.js","webpack:///../ckeditor5-utils/src/lib/lodash/isObjectLike.js","webpack:///../ckeditor5-utils/src/lib/lodash/isPlainObject.js","webpack:///../ckeditor5-utils/src/config.js","webpack:///../ckeditor5-core/src/plugincollection.js","webpack:///../ckeditor5-core/src/commandcollection.js","webpack:///../ckeditor5-utils/src/eventinfo.js","webpack:///../ckeditor5-utils/src/lib/lodash/_assignValue.js","webpack:///../ckeditor5-utils/src/lib/lodash/_copyObject.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseProperty.js","webpack:///../ckeditor5-utils/src/lib/lodash/_getLength.js","webpack:///../ckeditor5-utils/src/lib/lodash/isObject.js","webpack:///../ckeditor5-utils/src/lib/lodash/isFunction.js","webpack:///../ckeditor5-utils/src/lib/lodash/isLength.js","webpack:///../ckeditor5-utils/src/lib/lodash/isArrayLike.js","webpack:///../ckeditor5-utils/src/lib/lodash/_isIndex.js","webpack:///../ckeditor5-utils/src/lib/lodash/_isIterateeCall.js","webpack:///../ckeditor5-utils/src/lib/lodash/_apply.js","webpack:///../ckeditor5-utils/src/lib/lodash/isSymbol.js","webpack:///../ckeditor5-utils/src/lib/lodash/toNumber.js","webpack:///../ckeditor5-utils/src/lib/lodash/toFinite.js","webpack:///../ckeditor5-utils/src/lib/lodash/toInteger.js","webpack:///../ckeditor5-utils/src/lib/lodash/_createAssigner.js","webpack:///../ckeditor5-utils/src/lib/lodash/_isPrototype.js","webpack:///../ckeditor5-utils/src/lib/lodash/_Reflect.js","webpack:///../ckeditor5-utils/src/lib/lodash/_iteratorToArray.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseTimes.js","webpack:///../ckeditor5-utils/src/lib/lodash/isArrayLikeObject.js","webpack:///../ckeditor5-utils/src/lib/lodash/isArguments.js","webpack:///../ckeditor5-utils/src/lib/lodash/isArray.js","webpack:///../ckeditor5-utils/src/lib/lodash/isString.js","webpack:///../ckeditor5-utils/src/lib/lodash/_indexKeys.js","webpack:///../ckeditor5-utils/src/lib/lodash/keysIn.js","webpack:///../ckeditor5-utils/src/lib/lodash/assignIn.js","webpack:///../ckeditor5-utils/src/lib/lodash/extend.js","webpack:///../ckeditor5-engine/src/model/text.js","webpack:///../ckeditor5-engine/src/model/textproxy.js","webpack:///../ckeditor5-engine/src/model/nodelist.js","webpack:///../ckeditor5-engine/src/model/range.js","webpack:///../ckeditor5-utils/src/lib/lodash/_listCacheClear.js","webpack:///../ckeditor5-utils/src/lib/lodash/_assocIndexOf.js","webpack:///../ckeditor5-utils/src/lib/lodash/_listCacheDelete.js","webpack:///../ckeditor5-utils/src/lib/lodash/_listCacheGet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_listCacheHas.js","webpack:///../ckeditor5-utils/src/lib/lodash/_listCacheSet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_stackClear.js","webpack:///../ckeditor5-utils/src/lib/lodash/_toSource.js","webpack:///../ckeditor5-utils/src/lib/lodash/isNative.js","webpack:///../ckeditor5-utils/src/lib/lodash/_getNative.js","webpack:///../ckeditor5-utils/src/lib/lodash/_nativeCreate.js","webpack:///../ckeditor5-utils/src/lib/lodash/_hashClear.js","webpack:///../ckeditor5-utils/src/lib/lodash/_hashGet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_hashHas.js","webpack:///../ckeditor5-utils/src/lib/lodash/_hashDelete.js","webpack:///../ckeditor5-utils/src/lib/lodash/_hashSet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_Map.js","webpack:///../ckeditor5-utils/src/lib/lodash/_mapCacheClear.js","webpack:///../ckeditor5-utils/src/lib/lodash/_getMapData.js","webpack:///../ckeditor5-utils/src/lib/lodash/_isKeyable.js","webpack:///../ckeditor5-utils/src/lib/lodash/_mapCacheDelete.js","webpack:///../ckeditor5-utils/src/lib/lodash/_mapCacheGet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_mapCacheHas.js","webpack:///../ckeditor5-utils/src/lib/lodash/_mapCacheSet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_stackSet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_stackDelete.js","webpack:///../ckeditor5-utils/src/lib/lodash/_stackGet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_stackHas.js","webpack:///../ckeditor5-utils/src/lib/lodash/_arrayEach.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseHas.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseKeys.js","webpack:///../ckeditor5-utils/src/lib/lodash/keys.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseAssign.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cloneBuffer.js","webpack:///../ckeditor5-utils/src/lib/lodash/_copyArray.js","webpack:///../ckeditor5-utils/src/lib/lodash/_copySymbols.js","webpack:///../ckeditor5-utils/src/lib/lodash/_arrayPush.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseGetAllKeys.js","webpack:///../ckeditor5-utils/src/lib/lodash/_getAllKeys.js","webpack:///../ckeditor5-utils/src/lib/lodash/_DataView.js","webpack:///../ckeditor5-utils/src/lib/lodash/_Promise.js","webpack:///../ckeditor5-utils/src/lib/lodash/_Set.js","webpack:///../ckeditor5-utils/src/lib/lodash/_WeakMap.js","webpack:///../ckeditor5-utils/src/lib/lodash/_initCloneArray.js","webpack:///../ckeditor5-utils/src/lib/lodash/_Uint8Array.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cloneArrayBuffer.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cloneDataView.js","webpack:///../ckeditor5-utils/src/lib/lodash/_addMapEntry.js","webpack:///../ckeditor5-utils/src/lib/lodash/_arrayReduce.js","webpack:///../ckeditor5-utils/src/lib/lodash/_mapToArray.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cloneMap.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cloneRegExp.js","webpack:///../ckeditor5-utils/src/lib/lodash/_addSetEntry.js","webpack:///../ckeditor5-utils/src/lib/lodash/_setToArray.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cloneSet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_Symbol.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cloneSymbol.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cloneTypedArray.js","webpack:///../ckeditor5-utils/src/lib/lodash/_initCloneByTag.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseCreate.js","webpack:///../ckeditor5-utils/src/lib/lodash/_initCloneObject.js","webpack:///../ckeditor5-utils/src/lib/lodash/clone.js","webpack:///../ckeditor5-engine/src/view/node.js","webpack:///../ckeditor5-engine/src/view/text.js","webpack:///../ckeditor5-engine/src/view/treewalker.js","webpack:///../ckeditor5-engine/src/view/position.js","webpack:///../ckeditor5-engine/src/conversion/modelconsumable.js","webpack:///../ckeditor5-engine/src/conversion/viewconsumable.js","webpack:///../ckeditor5-engine/src/model/operation/operation.js","webpack:///../ckeditor5-utils/src/lib/lodash/_setCacheAdd.js","webpack:///../ckeditor5-utils/src/lib/lodash/_setCacheHas.js","webpack:///../ckeditor5-utils/src/lib/lodash/_arraySome.js","webpack:///../ckeditor5-utils/src/lib/lodash/_equalArrays.js","webpack:///../ckeditor5-utils/src/lib/lodash/_equalByTag.js","webpack:///../ckeditor5-utils/src/lib/lodash/_equalObjects.js","webpack:///../ckeditor5-utils/src/lib/lodash/isTypedArray.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseIsEqualDeep.js","webpack:///../ckeditor5-utils/src/lib/lodash/isEqual.js","webpack:///../ckeditor5-engine/src/model/operation/attributeoperation.js","webpack:///../ckeditor5-engine/src/model/operation/moveoperation.js","webpack:///../ckeditor5-engine/src/model/operation/reinsertoperation.js","webpack:///../ckeditor5-engine/src/model/operation/removeoperation.js","webpack:///../ckeditor5-engine/src/model/operation/insertoperation.js","webpack:///../ckeditor5-engine/src/model/operation/markeroperation.js","webpack:///../ckeditor5-engine/src/model/operation/nooperation.js","webpack:///../ckeditor5-engine/src/model/operation/renameoperation.js","webpack:///../ckeditor5-engine/src/model/operation/rootattributeoperation.js","webpack:///../ckeditor5-engine/src/model/operation/operationfactory.js","webpack:///../ckeditor5-engine/src/model/delta/deltafactory.js","webpack:///../ckeditor5-engine/src/model/delta/delta.js","webpack:///../ckeditor5-engine/src/model/delta/insertdelta.js","webpack:///../ckeditor5-engine/src/model/delta/splitdelta.js","webpack:///../ckeditor5-engine/src/model/delta/mergedelta.js","webpack:///../ckeditor5-engine/src/model/delta/wrapdelta.js","webpack:///../ckeditor5-engine/src/model/delta/unwrapdelta.js","webpack:///../ckeditor5-engine/src/model/delta/weakinsertdelta.js","webpack:///../ckeditor5-engine/src/model/delta/basic-deltas.js","webpack:///../ckeditor5-utils/src/lib/lodash/chunk.js","webpack:///../ckeditor5-utils/src/lib/lodash/_isFlattenable.js","webpack:///../ckeditor5-utils/src/lib/lodash/concat.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseIndexOf.js","webpack:///../ckeditor5-utils/src/lib/lodash/_indexOfNaN.js","webpack:///../ckeditor5-utils/src/lib/lodash/_arrayIncludes.js","webpack:///../ckeditor5-utils/src/lib/lodash/_arrayIncludesWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/_arrayMap.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseUnary.js","webpack:///../ckeditor5-utils/src/lib/lodash/_cacheHas.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseDifference.js","webpack:///../ckeditor5-utils/src/lib/lodash/difference.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseIsMatch.js","webpack:///../ckeditor5-utils/src/lib/lodash/_isStrictComparable.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseToPairs.js","webpack:///../ckeditor5-utils/src/lib/lodash/_setToPairs.js","webpack:///../ckeditor5-utils/src/lib/lodash/_createToPairs.js","webpack:///../ckeditor5-utils/src/lib/lodash/toPairs.js","webpack:///../ckeditor5-utils/src/lib/lodash/_getMatchData.js","webpack:///../ckeditor5-utils/src/lib/lodash/_matchesStrictComparable.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseMatches.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseToString.js","webpack:///../ckeditor5-utils/src/lib/lodash/toString.js","webpack:///../ckeditor5-utils/src/lib/lodash/_stringToPath.js","webpack:///../ckeditor5-utils/src/lib/lodash/_castPath.js","webpack:///../ckeditor5-utils/src/lib/lodash/_isKey.js","webpack:///../ckeditor5-utils/src/lib/lodash/_toKey.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseGet.js","webpack:///../ckeditor5-utils/src/lib/lodash/get.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseHasIn.js","webpack:///../ckeditor5-utils/src/lib/lodash/_hasPath.js","webpack:///../ckeditor5-utils/src/lib/lodash/hasIn.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseMatchesProperty.js","webpack:///../ckeditor5-utils/src/lib/lodash/identity.js","webpack:///../ckeditor5-utils/src/lib/lodash/_basePropertyDeep.js","webpack:///../ckeditor5-utils/src/lib/lodash/property.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseIteratee.js","webpack:///../ckeditor5-utils/src/lib/lodash/differenceBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/differenceWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/drop.js","webpack:///../ckeditor5-utils/src/lib/lodash/dropRight.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseWhile.js","webpack:///../ckeditor5-utils/src/lib/lodash/dropRightWhile.js","webpack:///../ckeditor5-utils/src/lib/lodash/toLength.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseClamp.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseFill.js","webpack:///../ckeditor5-utils/src/lib/lodash/fill.js","webpack:///../ckeditor5-utils/src/lib/lodash/findIndex.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseFindIndex.js","webpack:///../ckeditor5-utils/src/lib/lodash/flatten.js","webpack:///../ckeditor5-utils/src/lib/lodash/head.js","webpack:///../ckeditor5-utils/src/lib/lodash/_castArrayLikeObject.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseIntersection.js","webpack:///../ckeditor5-utils/src/lib/lodash/intersection.js","webpack:///../ckeditor5-utils/src/lib/lodash/intersectionBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/intersectionWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/join.js","webpack:///../ckeditor5-utils/src/lib/lodash/nth.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseNth.js","webpack:///../ckeditor5-utils/src/lib/lodash/_basePullAll.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseIndexOfWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/pullAll.js","webpack:///../ckeditor5-utils/src/lib/lodash/pull.js","webpack:///../ckeditor5-utils/src/lib/lodash/pullAllBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/_parent.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseAt.js","webpack:///../ckeditor5-utils/src/lib/lodash/_basePullAt.js","webpack:///../ckeditor5-utils/src/lib/lodash/_compareAscending.js","webpack:///../ckeditor5-utils/src/lib/lodash/pullAt.js","webpack:///../ckeditor5-utils/src/lib/lodash/remove.js","webpack:///../ckeditor5-utils/src/lib/lodash/reverse.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseSortedIndex.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseSortedIndexBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/sortedIndex.js","webpack:///../ckeditor5-utils/src/lib/lodash/sortedUniq.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseSortedUniq.js","webpack:///../ckeditor5-utils/src/lib/lodash/_createSet.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseUniq.js","webpack:///../ckeditor5-utils/src/lib/lodash/noop.js","webpack:///../ckeditor5-utils/src/lib/lodash/union.js","webpack:///../ckeditor5-utils/src/lib/lodash/unionBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/unionWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/uniq.js","webpack:///../ckeditor5-utils/src/lib/lodash/unzip.js","webpack:///../ckeditor5-utils/src/lib/lodash/_arrayFilter.js","webpack:///../ckeditor5-utils/src/lib/lodash/unzipWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/without.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseXor.js","webpack:///../ckeditor5-utils/src/lib/lodash/xor.js","webpack:///../ckeditor5-utils/src/lib/lodash/xorBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/xorWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/zip.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseZipObject.js","webpack:///../ckeditor5-utils/src/lib/lodash/zipObject.js","webpack:///../ckeditor5-utils/src/lib/lodash/zipObjectDeep.js","webpack:///../ckeditor5-utils/src/lib/lodash/_baseSet.js","webpack:///../ckeditor5-utils/src/lib/lodash/zipWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/array.default.js","webpack:///../ckeditor5-utils/src/lib/lodash/compact.js","webpack:///../ckeditor5-utils/src/lib/lodash/dropWhile.js","webpack:///../ckeditor5-utils/src/lib/lodash/findLastIndex.js","webpack:///../ckeditor5-utils/src/lib/lodash/flattenDeep.js","webpack:///../ckeditor5-utils/src/lib/lodash/flattenDepth.js","webpack:///../ckeditor5-utils/src/lib/lodash/fromPairs.js","webpack:///../ckeditor5-utils/src/lib/lodash/indexOf.js","webpack:///../ckeditor5-utils/src/lib/lodash/initial.js","webpack:///../ckeditor5-utils/src/lib/lodash/lastIndexOf.js","webpack:///../ckeditor5-utils/src/lib/lodash/pullAllWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/slice.js","webpack:///../ckeditor5-utils/src/lib/lodash/sortedIndexBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/sortedIndexOf.js","webpack:///../ckeditor5-utils/src/lib/lodash/sortedLastIndex.js","webpack:///../ckeditor5-utils/src/lib/lodash/sortedLastIndexBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/sortedLastIndexOf.js","webpack:///../ckeditor5-utils/src/lib/lodash/sortedUniqBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/tail.js","webpack:///../ckeditor5-utils/src/lib/lodash/take.js","webpack:///../ckeditor5-utils/src/lib/lodash/takeRight.js","webpack:///../ckeditor5-utils/src/lib/lodash/takeRightWhile.js","webpack:///../ckeditor5-utils/src/lib/lodash/takeWhile.js","webpack:///../ckeditor5-utils/src/lib/lodash/uniqBy.js","webpack:///../ckeditor5-utils/src/lib/lodash/uniqWith.js","webpack:///../ckeditor5-utils/src/lib/lodash/array.js","webpack:///../ckeditor5-engine/src/model/history.js","webpack:///../ckeditor5-core/src/editingkeystrokehandler.js","webpack:///../ckeditor5-engine/src/view/observer/observer.js","webpack:///../ckeditor5-utils/src/lib/lodash/isEqualWith.js","webpack:///../ckeditor5-engine/src/view/observer/mutationobserver.js","webpack:///../ckeditor5-utils/src/lib/lodash/now.js","webpack:///../ckeditor5-utils/src/lib/lodash/debounce.js","webpack:///../ckeditor5-engine/src/view/observer/selectionobserver.js","webpack:///../ckeditor5-engine/src/view/observer/domeventdata.js","webpack:///../ckeditor5-engine/src/view/observer/domeventobserver.js","webpack:///../ckeditor5-engine/src/view/observer/focusobserver.js","webpack:///../ckeditor5-engine/src/view/observer/keyobserver.js","webpack:///../ckeditor5-engine/src/dataprocessor/basichtmlwriter.js","webpack:///../ckeditor5-engine/src/dataprocessor/htmldataprocessor.js","webpack:///../ckeditor5-core/src/plugin.js","webpack:///../ckeditor5-utils/src/collection.js","webpack:///../ckeditor5-utils/src/focustracker.js","webpack:///../ckeditor5-ui/src/editorui/editoruiview.js","webpack:///../ckeditor5-ui/src/editableui/editableuiview.js","webpack:///../ckeditor5-ui/src/editableui/inline/inlineeditableuiview.js","webpack:///../ckeditor5-editor-balloon/src/ballooneditoruiview.js","webpack:///../ckeditor5-editor-balloon/src/ballooneditor.js","webpack:///../ckeditor5-core/src/command.js","webpack:///../ckeditor5-enter/src/enter.js","webpack:///../ckeditor5-typing/src/inputcommand.js","webpack:///../ckeditor5-typing/src/deleteobserver.js","webpack:///../ckeditor5-typing/src/delete.js","webpack:///../ckeditor5-typing/src/typing.js","webpack:///../ckeditor5-undo/src/redocommand.js","webpack:///../ckeditor5-undo/src/undoengine.js","webpack:///../ckeditor5-ui/src/icon/iconview.js","webpack:///../ckeditor5-ui/src/tooltip/tooltipview.js","webpack:///../ckeditor5-ui/src/button/buttonview.js","webpack:///../ckeditor5-undo/src/undo.js","webpack:///../ckeditor5-essentials/src/essentials.js","webpack:///../ckeditor5-upload/src/filereader.js","webpack:///../ckeditor5-upload/src/filerepository.js","webpack:///../ckeditor5-autoformat/src/blockautoformatengine.js","webpack:///../ckeditor5-basic-styles/src/boldengine.js","webpack:///../ckeditor5-basic-styles/src/bold.js","webpack:///../ckeditor5-basic-styles/src/italicengine.js","webpack:///../ckeditor5-basic-styles/src/italic.js","webpack:///../ckeditor5-block-quote/src/blockquote.js","webpack:////workspace/ckeditor5/node_modules/@ckeditor/ckeditor-cloudservices-core/src/token/token.js","webpack:///../ckeditor5-cloudservices/src/cloudservices.js","webpack:///../ckeditor5-easy-image/src/cloudservicesuploadadapter.js","webpack:///../ckeditor5-image/src/imagetextalternative/imagetextalternativeengine.js","webpack:///../ckeditor5-ui/src/labeledinput/labeledinputview.js","webpack:///../ckeditor5-ui/src/inputtext/inputtextview.js","webpack:///../ckeditor5-image/src/imagetextalternative.js","webpack:///../ckeditor5-image/src/image.js","webpack:///../ckeditor5-upload/src/imageuploadcommand.js","webpack:///../ckeditor5-ui/src/notification/notification.js","webpack:///../ckeditor5-upload/src/imageuploadbutton.js","webpack:///../ckeditor5-easy-image/src/easyimage.js","webpack:///../ckeditor5-ui/src/model.js","webpack:///../ckeditor5-ui/src/list/listview.js","webpack:///../ckeditor5-ui/src/list/listitemview.js","webpack:///../ckeditor5-ui/src/dropdown/dropdownview.js","webpack:///../ckeditor5-ui/src/dropdown/dropdownpanelview.js","webpack:///../ckeditor5-image/src/imagecaption.js","webpack:///../ckeditor5-image/src/imagestyle/imagestylecommand.js","webpack:///../ckeditor5-image/src/imagetoolbar.js","webpack:///../ckeditor5-engine/src/view/observer/clickobserver.js","webpack:///../ckeditor5-link/src/linkelement.js","webpack:///../ckeditor5-link/src/unlinkcommand.js","webpack:///../ckeditor5-link/src/linkengine.js","webpack:///../ckeditor5-link/src/ui/linkformview.js","webpack:///../ckeditor5-list/src/list.js","webpack:///./src/ckeditor.js","webpack:///(webpack)/buildin/global.js","webpack:///../ckeditor5-utils/src/lib/lodash/_checkGlobal.js","webpack:///../ckeditor5-utils/src/lib/lodash/isBuffer.js","webpack:///../ckeditor5-utils/src/lib/lodash/constant.js","webpack:///../ckeditor5-editor-balloon/theme/theme.scss?d822","webpack:///../ckeditor5-editor-balloon/theme/theme.scss","webpack:////workspace/ckeditor5/node_modules/style-loader/lib/urls.js","webpack:///../ckeditor5-undo/theme/icons/undo.svg","webpack:///../ckeditor5-undo/theme/icons/redo.svg","webpack:///../ckeditor5-basic-styles/theme/icons/bold.svg","webpack:///../ckeditor5-basic-styles/theme/icons/italic.svg","webpack:///../ckeditor5-core/theme/icons/quote.svg","webpack:///../ckeditor5-block-quote/theme/theme.scss?df4a","webpack:///../ckeditor5-block-quote/theme/theme.scss","webpack:///../ckeditor5-widget/theme/theme.scss?451e","webpack:///../ckeditor5-widget/theme/theme.scss","webpack:///../ckeditor5-core/theme/icons/low-vision.svg","webpack:///../ckeditor5-image/theme/imagetextalternative/theme.scss?8aba","webpack:///../ckeditor5-image/theme/imagetextalternative/theme.scss","webpack:///../ckeditor5-image/theme/theme.scss?490e","webpack:///../ckeditor5-image/theme/theme.scss","webpack:///../ckeditor5-core/theme/icons/image.svg","webpack:///../ckeditor5-upload/theme/icons/image_placeholder.svg","webpack:///../ckeditor5-upload/theme/imageuploadprogress.scss?ba59","webpack:///../ckeditor5-upload/theme/imageuploadprogress.scss","webpack:///../ckeditor5-heading/theme/theme.scss?f3a2","webpack:///../ckeditor5-heading/theme/theme.scss","webpack:///../ckeditor5-engine/theme/placeholder.scss?9710","webpack:///../ckeditor5-engine/theme/placeholder.scss","webpack:///../ckeditor5-image/theme/imagecaption/theme.scss?3012","webpack:///../ckeditor5-image/theme/imagecaption/theme.scss","webpack:///../ckeditor5-core/theme/icons/object-full-width.svg","webpack:///../ckeditor5-core/theme/icons/object-left.svg","webpack:///../ckeditor5-core/theme/icons/object-center.svg","webpack:///../ckeditor5-core/theme/icons/object-right.svg","webpack:///../ckeditor5-link/theme/icons/link.svg","webpack:///../ckeditor5-link/theme/theme.scss?9387","webpack:///../ckeditor5-link/theme/theme.scss","webpack:///../ckeditor5-list/theme/icons/numberedlist.svg","webpack:///../ckeditor5-list/theme/icons/bulletedlist.svg"],"names":[],"mappings":";;;;AAAA,cACA,2BACA,uCACA,sCACA,IACA,aACA,+CAEA,oBACA,GAAC,mBACD,kBCTA,cAMA,IACA,iBAGA,mBACA,CACA,IACA,KAIA,2CAGA,aAGA,OACA,OAIA,IAzBA,eA4BA,MAGA,uBACA,GACA,kCACA,CACA,gBACA,cAGA,OAGA,iBACA,YACA,qBAA2B,UAA0B,UACrD,YAAiC,CAAe,QAChD,EAEA,aADA,QAIA,mBAAsD,wCAA+D,SAGrH,MAGA,yBCzDA,CA6CA,eACA,aACA,OACA,MACA,GAGA,uCACA,OACA,gCACA,uCACA,KAEA,wCACA,KAEA,gBACA,KAEA,CACA,aAEA,6CACA,8BAEA,kEACA,MAtEA,qBACA,IAGA,MAsCA,4BArCA,4BACA,OACA,gBACA,kBAAmC,MAInC,KAAG,QACH,GAGA,mBACA,CACA,gCACA,aACA,QAAgB,WAAiB,OACjC,cACA,GACA,qBAEA,eAAY,MAAoB,WAChC,OAKA,gCACA,YACA,KAEA,mCAEA,OAEA,QACA,CACA,qBC3CA,CA6FA,eACA,WAAgB,MAAmB,WACnC,OACA,WAEA,SACA,GAEA,iBAAiB,YAA2B,OAC5C,iBAGA,UAAQ,eAAuB,OAC/B,qBAEA,YAAG,KACH,QAEA,QAAiB,YAAuB,OACxC,eAGA,sBAA2B,eAC3B,QACA,CACA,EAEA,eACA,QACA,MAEA,OAAgB,MAAiB,WACjC,OACA,4BACA,OACA,OACA,OACA,MAAc,cAEd,6BAEA,qBAFkD,WAClD,KAGA,CACA,SAEA,eACA,WAEA,eACA,mBAGA,mIAEA,MAEA,uBAEA,+BAEA,eAEA,kCALG,cAMD,gBACF,wBAEA,oCAEA,4EAEA,aACA,wBACA,sBAEA,uBACA,WACA,iBAEA,GAEA,aACA,8BAEA,SAMA,oBAJA,iBACA,OAEA,SAGA,aACA,8BAEA,QAOA,oBANA,uBAEA,mBACA,OAEA,SAGA,eACA,mCACA,kBACA,KACA,GAEA,eACA,WAGA,oBACA,IAKA,mBAHA,SAOA,4BAEA,CAIA,iBACA,OAEA,YAEA,eACA,sBAEA,YACA,QACA,WACA,wBACA,wCACA,wCACA,yBAEA,2BACA,cACA,sBACA,CAEA,mCACA,KAEA,MACA,cACA,oBACA,CACA,IAGA,SAEA,iBACA,MACA,CACA,aACA,iBACA,uBAEA,UAGA,SACA,IACA,KAEA,IACA,EAYA,mBACA,cAEA,SACA,gCACE,WACF,gBACA,sBAEA,+BAEA,QACA,wBAEA,QAEA,cACA,EAEA,eACA,SACA,QAGA,2BAGA,aACA,wBACE,cACF,QACA,4BAGA,mCACA,kBACA,EAEA,iBACA,SACA,QAQA,cAEA,qCACA,8BAKA,aAAuD,6GAGvD,0BAA6B,MAE7B,iBAEA,gBAEA,0BACA,mBA3VA,GAEA,mBACA,IAEA,oBACA,CAEA,6CADA,aAEA,CAEA,YAMA,gDACA,IAEA,gBACA,IAEA,wBACA,OACA,uCAGA,SACA,IACA,CAAC,aACD,iBACA,gBAEA,KACA,OACA,EAEA,aAEA,uBACA,+BACA,iDAGA,kEAEA,yCAIA,mCAGA,iCAGA,gCAEA,gBAEA,aAEA,mBACA,QAEA,QAAiB,MAAmB,WACpC,OACA,WAEA,MACA,SACA,OAEA,MACA,OACA,OACA,MAEA,WAAiB,QAAsB,OACvC,SAEA,gBACA,WAAmB,YAA2B,aAE9C,sBACA,GAEA,CACA,GAsLA,gBACA,IAEA,0BACA,OAEA,+BACA,KACA,CAAC,yDCzRD,GAMA,iEACA,SAIA,oCAKA,sCAGA,qDAGA,sCAGA,sCAQA,QACA,aACA,2BAEA,2DCxCA,qBACA,uBACA,cAEA,yBACA,8CACA,CACA,4BACA,UACA,CAEA,iCACA,CACA,4BACA,UACA,CAEA,sCACA,CAEA,kCACA,CACA,CACA,wCCsDA,aACA,iBAMA,wBAAiC,iBAAuB,QACxD,MCzCA,CCCA,eACA,OACA,QAIA,2CADA,GAGA,CACA,eACA,CACA,MACA,cAEA,MC9CA,CCmBA,kBACA,gBACA,6CACA,uCACA,aAIA,2BACA,gCAEA,sCACA,eACA,EACA,EC7BA,CCFA,YACA,OAEA,cAAiB,EAAO,IACxB,0DAGA,GACA,QCJA,CC+WA,eACA,eACA,kBAGA,QACA,IAUA,CACA,eACA,CACA,iBAEA,IAOA,CACA,aACA,OACA,MAIA,CACA,aACA,UACA,2CACA,CAIA,aACA,OAEA,CACA,YACA,OACA,CACA,aAEA,eAMA,CACA,eACA,SAGA,QAEA,KASA,UAEA,OAGA,UAKA,WACA,SAQA,WAEA,WAIA,0BAGA,QAEA,+BAGA,gBAKA,UACA,mCAIA,yBACA,OACA,CAKA,CACA,eACA,SAEA,WACA,GAGA,kBAEA,qBAAiB,kBAAkC,WACnD,eAEA,oBACA,SAEA,CACA,QAIA,CACA,eACA,IAEA,mDAGA,SAUA,WARA,8CAGA,OAIA,IAQuB,CACvB,iBACA,kBAEA,GAEA,6BAGA,WAJG,sBAMH,uBAEA,eACA,KACA,CC3hBA,CCbA,aACA,aAEA,aACA,aACA,UAEA,QACA,QAGA,CCuUA,aAEA,CAQA,qCACA,UAgDA,kCACA,UA+BA,kCACA,UAEA,OAK2C,CAC3C,gBACA,WACA,kCACA,YAGA,uBAMA,2BAIA,uGAMA,sBAGA,2HAEA,4BAMA,wBAKA,iFACA,sBAEA,WAEA,cAGA,KACA,+CAGA,kCAGA,OAGA,mCACA,QACA,cACA,EAMa,CACb,aACA,qBACA,mBAmBa,CACb,gBAEA,OAMA,oBAGA,8EAAiB,CACjB,UAEA,GAgBA,MAfA,gDAGA,sBACA,IACA,2BACG,gBACH,qBAAqB,cACrB,eAEA,0BAEA,qEAEA,IAQkB,CAClB,mBACA,SACA,UACA,SAEA,MACA,eAIA,WAGA,YAEA,QAuC8E,CAC9E,aACA,IAEA,8BAIA,oBACA,qCAEA,yBACA,mCACA,aACA,EACA,EAOkB,CAClB,eACA,SACA,UACA,UAOA,KACA,mDAEA,cACA,YAGA,OACA,kBAEA,SAEA,QAO4E,CAC5E,eACA,gBACA,SACA,SAIA,WACA,qDACA,WAKA,iCACA,OACA,KAEA,EAEA,EACA,GCprBA,aACA,YAEA,cACA,gBAGA,MACA,QCLA,CACA,aACA,OACA,OAEA,QAEA,OCWA,CCxBA,aACA,sBACA,UCEA,CAgSA,aAEA,OACA,oBAGA,YACA,SAIA,WACA,YACA,wBAEA,aCjTA,CA0UA,qBACA,OACA,CACA,cACA,CACA,OACA,OACA,mBACA,eAGA,UCzVA,CCYA,eACA,uBAEA,kBAAiB,EAAY,IAC7B,aAEA,KAKA,4BAEA,OACE,kBAEF,OAGA,SAEA,WCVA,CCvBA,aACA,QACA,eAEA,WACA,eACA,OACA,qBACA,GACA,CAEA,CCXA,aACA,QACA,eAEA,WACA,eACA,OACA,qBACA,GACA,CAEA,CCXA,aACA,QACA,eAEA,WACA,eACA,OACA,qBACA,GACA,CAEA,CCVA,aACA,eACA,SAEA,CCRA,aAGA,WACA,UAIA,CCsBA,aACA,WACA,OAIA,CC+BA,yBACA,IAEA,yBAEA,MACA,WAEA,aACA,MAEA,eACA,MACA,MAKA,OACA,eAEA,gBACA,eAEA,gCACA,IACA,YAEA,gBACA,QACA,eAEA,QAAK,KACL,KACA,YAEA,UACA,WACA,CAEA,WA1BA,MACA,SAEG,eAwBH,gBACA,OACA,KAEA,cAEA,SACA,iBAGA,MAQA,4BANA,KACA,MAEA,aACA,iBACA,IAGA,CCoFA,eAEA,IACA,2BAGA,WAEA,eACA,yBAEA,SACA,MAKA,OACA,4BAEA,gBACA,WAKA,OACA,oBAEA,YAMA,YACA,oBAEA,YAMA,WAMqB,CACrB,eAEA,oBACA,UAGA,QACA,KAOwB,CACxB,eACA,MAEA,uBACA,SAEA,0BACA,WAEA,+BACA,cACA,UAEA,mBAEI,eACJ,QAEA,mBAEA,KACA,YAEA,KAEA,CACA,QAMwB,CACxB,eACA,MAEA,eACA,+BACA,WAEA,yBACA,UACA,WAIA,WACA,mBAEA,KAAG,WACH,cAEA,mBAIA,MACA,QAOwB,CACxB,eACA,MAEA,uBACA,SAEA,sBACA,WAEA,2BACA,cACA,UAEA,mBAEI,eACJ,QAEA,mBAEA,KACA,YAEA,KAEA,CACA,QC/VA,CA2rBA,eAEA,OACA,OACA,IACA,IAEA,UAGA,QAKA,QACA,+BAIA,eAAiB,MAAyB,WAC1C,WAEA,aAEA,QACA,cAMA,qBAEA,SAGA,GAEA,UACA,QAEA,KAEA,IAGA,UAGA,uBAIA,yBAGA,UAGA,SAIG,OAEH,WAEA,KACA,EAMkB,CAClB,eACA,iBACA,SACA,yBACA,OAKY,CACZ,aAEA,OACA,oBAGA,YACA,SAIA,WACA,YACA,wBAEA,aC9xBA,CCiDA,YACA,qBAEA,uBACA,mBAKA,kBACA,UC7EA,CCgcA,aACA,iDAKA,YCjbA,CCqRA,aAEA,OACA,oBAGA,YACA,SAIA,WACA,YACA,wBAEA,aC1NA,CA8mBA,iBACA,WACA,0BACA,kBACA,UAEA,8BACA,sBACA,WAEA,6CACA,eACA,CAEA,SACA,EC7tBA,CA0FA,YAEA,MACA,YAGA,iBAGA,yCACA,IACA,aAGA,UACA,MAEA,WACA,OAIA,UACA,UAKY,CACZ,aACA,oEACA,MCrHA,CAsDA,YACA,OACA,KC9DA,CC4BA,cACA,IAEA,MACA,uBAaA,yBACA,sBACA,wBAGA,kBAhBA,eAOA,0DAAwE,CAGxE,QAOA,QAmBA,CACA,cACA,OACA,uBAGA,OACA,8BACA,2BACA,EAQA,CACA,cACA,SAEA,gBACA,KACA,2CAKA,MA6CA,cACA,gBACA,WCzIA,CA6EA,cACA,gCACA,cAIa,CACb,aACA,OACA,KAIA,CACA,kBACA,6BACA,+CACA,kDAGA,2BACA,WACA,cAEA,gBAGA,0BACA,SAIA,UAEA,wCACA,gBAEA,eAIA,wCAUA,2BACA,WAIA,6CAGA,4BAEA,OACA,CACA,CACA,CC9IA,CA2LA,cAEA,OACA,oBAGA,YACA,SAIA,WACA,YACA,wBAEA,aChMA,CA0JA,cACA,WACA,WAGA,eACA,QAIA,uDACA,WACA,WACA,eAEA,YACA,YAEA,sBACA,OAGA,mBACA,GAIA,+BACA,cAGA,+EAEA,WACA,qCACA,iBAIA,YACA,YAEA,CACA,QAoBA,CA4CA,gBACA,eAGA,IAEA,cAEA,SAMA,gBAGA,kDAEA,8BACA,cACA,kBAGA,SACA,YACE,iBAEF,GACA,cAGA,iBAEA,YACA,YACA,CAaA,CACA,cACA,IAGA,QACA,kBAIA,aAAQ,SAAmC,OAC3C,aAEA,oBAGA,4BAGA,YACA,eACA,iBAGA,sBACA,SAYA,CA+DA,gBACA,IAEA,uBACA,GAEA,mBACA,WAEA,aAEA,WAEA,kBACA,YACA,QAGA,YACA,QAcA,CACA,gBACA,MACA,8BAGA,yCAGA,QACA,YAIA,mDACA,iBAEA,8BACA,QAEA,QAGA,gCACA,wBACA,wBAEA,oDACA,EAGA,MAAQ,SAAmC,OAC3C,aAGA,yBAGA,sCAGA,iBAGA,mBACA,cAEA,sBAEA,WACA,YAYA,CA2IA,cACA,SAEA,oBACA,IACA,GAEA,WACA,MAEA,CACA,QAS4C,CAC5C,mBACA,WACA,UAEA,OAGA,oBACA,cAEA,eACA,YAEA,SACA,mBACA,aAGA,kCAEA,aACA,WAekD,CAClD,mBACA,WACA,WAGA,sBAMA,6BAIA,yDAMA,0BAIA,iEACA,kBAIA,yBACA,gBAIA,8BACA,kBAGA,mBAKA,mBACA,iCAEA,SACA,QAIA,UACA,2BAEA,aACA,QAKA,KACA,iBAGA,MAGA,iBAGA,8BACA,iBAGA,sBAGA,mCAEA,gBACA,QACA,CAQ8C,CAC9C,oBACA,IACA,UAGA,gBACA,WAGA,8BACA,WACA,kBAGA,aACA,WAGA,sBACA,KACA,qBAKA,MACA,UACA,CAEA,WACA,8BAGA,cAEA,GAGA,OAEA,mBACA,MAGA,yBACA,UAGA,iBAGA,QACA,aACA,IAEA,IAEA,WACA,oCAQ8C,CAC9C,oBACA,IACA,UAEA,gBACA,WACA,mBACA,eACA,2BACA,uBAGA,oCAEA,WAGA,UACA,WACA,oBAEA,2BACA,YAGA,kBAGA,cACA,GAGA,OAEA,mBACA,MAGA,YACA,UAGA,iBAGA,QACA,aACA,IAEA,IAEA,WACA,oCASa,CACb,gBACA,iBACA,SACE,8BAKF,6BACA,aAUA,CACA,cACA,WAEA,sBACA,+BAGA,kBAEA,yBACA,iBAIA,IASkD,CAClD,cACA,4BACA,oDAGA,MACA,oDAIA,qCAGA,qDAGA,wDAGA,iDACA,EAOkD,CAClD,gBAEA,gBACA,wBACA,OAEA,SACA,WAQqB,CACrB,gBAEA,oCACA,SAIA,0BAEA,mCAKA,sDACA,gBAKA,0BACA,oDACA,YAKA,0BAEA,gCAKA,gBACA,oCAIA,mCACA,kBACA,4BAIA,8BACA,kBACA,eAIA,YACA,QAOqB,CACrB,gBAEA,oCACA,SAIA,0BAEA,mCAKA,wDACA,iBAKA,6BACA,iBAIA,0BAEA,qDACA,YAKA,0BAEA,gCAIA,eAIA,mBAMA,0BAHA,oCAEA,mBAQa,CACb,cACA,wDACA,uEACA,UAgBA,CACA,cACA,kBACA,kBASA,6BAGA,wCACA,cAEA,cACA,EAQA,cACA,2CACA,oBAM0C,CAC1C,cACA,cACA,cAEA,gBAQA,mBAEA,sCCtpCA,CACA,cACA,kBACA,SACA,kBACA,UAEA,SAIA,uBAIA,mDAEA,+BACA,WACA,YACA,CAWA,CACA,aACA,kBACA,qBAIA,mDACA,uBAEA,SACA,YACA,CAcA,CACA,cACA,kBACA,OAEA,KACA,qBACA,cAEA,cACA,eAEA,WACA,eAGA,UAIA,gBACA,gBAKA,0BAKA,uBACA,wBACA,QAIA,iBAEA,oCAEA,YACA,0CAEA,SACA,CAiCA,CACA,cACA,sBAA+D,SAE/D,oBACA,0BAIA,aAAS,OAAa,iCAEtB,mDACA,kBACA,CAkCA,CACA,cACA,sBAA+D,CAE/D,oBACA,0BAIA,aAAS,CAAM,+BAEf,mDACA,mBACA,CA4BA,CACA,cACA,kBACA,SACA,kBACA,cAEA,4BACA,GAGA,iCACA,OAGA,oCAKA,yDACA,aACA,8BACA,WAEA,IACA,SACA,CAuBA,CACA,cACA,kBACA,SACA,kBACA,cAEA,yBAIA,4BAIA,uCAEA,UACA,YACA,CAQA,CACA,aACA,kBACA,sBACA,UAQA,uCACA,gBAEA,eAOA,uDAEA,4CACA,6BAGA,yBACG,eAGH,qBACA,cACA,WAGA,aAeA,cACA,kEAEA,KACA,CASA,CACA,cACA,kBACA,SACA,qBAGA,eAEA,4CAIA,4BAIA,SACA,YAGA,oBACA,+BAEA,OACA,qCAEA,aAEA,YACA,CAiBA,CACA,cACA,kBACA,SACA,qBAGA,eAEA,4CAIA,4BAIA,SACA,sBAGA,MACA,YAGA,6BACA,mBACA,qDAEA,+CAEA,oBAGA,wBACA,+BAGA,qCACA,GACA,EACA,CASA,CACA,cACA,kBACA,OAEA,KACA,qBACA,cAEA,cACA,eAEA,WACA,eAGA,UAIA,gBACA,gBAGA,0BAKA,uBACA,wBACA,QAIA,wBAGA,0BAGA,mBACA,yBAEA,kBACA,CAOA,CACA,cACA,iBAEA,uBACA,EAIA,CACA,gBAEA,gBAAqC,iBAErC,4BAEA,WACA,WACA,iBAEA,IACA,eAIA,QASA,CACA,cACA,yBAEA,uBACA,2CACA,kBACA,KAEA,CAOA,SANA,wBAGA,wDAEA,KAaA,CC5jBA,gBACA,GAGA,6CACA,OAGA,OACA,gBAIA,eAGA,6BACA,QAEA,mBACA,gBAQA,CACA,cACA,OAMA,YAIA,oIAGA,YACA,YAGA,gEAIA,OAGA,oBADA,QASA,CAuEA,cACA,MAEA,kBACA,WAIA,eAAiB,MAAkB,OACnC,OACA,oCACG,eACH,+CACG,6CACH,gCACA,QAEG,YACH,2BAMA,gBAAiB,MAAuB,WACxC,SACA,WAEA,qCAEA,gDACA,kBAEA,IAEA,CACA,QAYA,CACA,gBACA,sBACA,OAGA,yDAEA,gCAGA,sCAGA,sBACA,IACA,CASA,CACA,cACA,WACA,aAEA,YACA,oBACA,gBAEA,yBAEA,uCACA,6CAEA,oCACA,MACA,CAUA,CACA,gBACA,WACA,oBAEA,iCACA,4BACA,IAGA,WACA,MAEA,iBACA,ICjMA,CA+KA,cACA,YACA,UAGA,cACA,6BACA,GAIA,+BAEA,QACA,gCAKA,uBACA,wBACA,kBAGA,kBACA,uBAOA,wCAJA,8BAKA,YAEA,CACA,QC9RA,CACA,aACA,kBAEA,iCAAwD,CAAa,UACrE,6BAEA,2BACA,MACA,CACA,CAMA,CACA,aACA,kBACA,SACA,MACA,iBAGA,kBACA,sBACA,iCAGA,MACA,CC/BA,CA4GA,aAEA,YAEA,iDACA,mBACA,SACA,kBACA,GACA,iCAEA,eACA,EAAG,UAEH,QAWA,CACA,kBAEA,8BACA,UAEA,GACA,cACA,iBACA,oEACA,WAEA,UACA,WACA,aACA,sBAEA,qDACA,8BACA,sDAGA,oCACA,6BACI,WACJ,SACA,iEACA,UAIA,sBACA,+BAEA,kBACA,iBAEA,eACA,WAEA,EC3KA,oBAEA,eAGA,WACA,eAGA,wCAEA,WAEA,UACA,sBAEA,cAGA,oBAGA,CACA,WAGA,sBAIA,kCAUA,aAEA,qFAMA,CAqXA,cACA,+BACA,ICjaA,CACA,gBAAqE,KACrE,OAIA,gCAIA,sCACA,QAKA,WAHA,mBAIA,oBACA,gCAGA,0BACA,QAWA,YACA,gBAOA,gDAGA,sBAIA,kBACA,SAGA,YACA,SAGA,CACA,kBACA,WACA,WAIA,UAOA,kBAOA,QAQA,kBACA,oBAEA,kBAKA,cAMA,YAOA,2BACA,WAEA,YAEA,kBACA,SAGA,CACA,WAEA,gBACA,iBAAsC,cACtC,qBAA2C,kBAE3C,iBACA,KAOA,CACA,gBACA,yBACA,SAEA,6BACA,+DACA,MAIA,SACA,SAEA,kBACA,gBACA,eAEA,cACA,kBAEA,gBACA,2BAEA,+BACA,qBACA,cAKA,CACA,gBACA,WAEA,yBACA,yBAGA,mBAEA,6CAIA,gBAAuB,2BACvB,MCrMA,CACA,cACA,+FACA,OAUA,CACA,cACA,2CACA,OAUA,CACA,cACA,2CACA,OAQA,CACA,gBACA,gCACA,UAQA,CACA,gBACA,aACA,UC1BA,CACA,gBAAgF,KAChF,iBACA,SACA,wCAEA,gBACA,eACA,YACA,QACA,0CAGA,eAAe,+BAEf,eAEA,eACA,MACA,KAGA,sBAEA,OACA,KAIA,cAFA,cAGA,CAEA,CACA,gBAGA,IACA,oCAIA,2DAEA,gCACA,oDAIA,4BAA2B,uBAC3B,wBAEA,YAEA,KAEA,+BAEA,MAMA,0BAJA,0BAI2B,uBAC3B,wBAEA,YACA,CAGA,CACA,gBACA,oBAEA,cACA,WACA,mCAEA,qCACA,WAEA,6BAEA,WAEA,UACA,SAEA,gBACA,WACA,6BAGA,YAEA,YAEA,WC9GA,CACA,cACA,SACA,WAEA,yBACA,YAGA,yBACA,+BACA,SAeA,oBAEA,yBAIA,YACA,6CACA,+BAIA,gCAGA,iCAAiD,CACjD,kBACA,8CAEA,qCAmBA,mBAEA,6DAEA,6BACA,oCAEA,QACA,MACA,KAEA,CACA,QAGA,CACA,cACA,MAEA,4BAA8B,WAG9B,0BAKA,yBAEA,MACA,gDACA,iDAEA,MACA,QACA,gBACA,gBAEA,QACA,KAIA,kBACA,QAEA,0BACA,YAEA,gBAEA,OACA,KACA,CACA,ECxGA,CC9BA,cACA,QACA,eAEA,oBACA,OACA,gBAEA,KAEA,CCHA,sBACA,SAGA,mCACA,OAGA,wBADA,MAGA,CC+GA,gBACA,OAOA,kBACA,QACA,uEAAI,CAGJ,YACA,cClIA,CA4IA,oBACA,CACA,uBAEA,uBAEA,gBAEA,sBACA,WACA,sBAEA,qCAEA,OACA,SAEA,iBAEA,kCAEA,iBAIA,oEAIA,iCAGA,mCAGA,YACA,kBAEA,kBAGA,CACA,sBACA,aAuCA,CACA,2BAGA,oBACA,+BAEA,WACA,kBACA,iBACA,SA9CA,eAIA,MAEA,EAEA,EAEA,WACA,iBAIA,mBAEA,OACA,MAGA,IAGA,SACA,aAKA,2BACA,MAGA,IC5JA,sBACA,iCACA,WACA,2BACA,iBASA,CCtEA,kBACA,SACA,SAEA,+BACA,YAEA,wCACA,WACA,2BACA,iBAQA,CCHA,kBACA,GACA,2BACA,iBASA,CC+hBA,cACA,UACA,QAGA,CACA,gBACA,WAAiB,MAAuB,OACxC,yBAGA,EACA,QAEA,CACA,gBACA,OACA,8EAIA,CACA,cACA,OACA,cACE,KACF,cAEA,2BAEA,MAEA,GAMA,CACA,kBAUA,MAGA,gBAAiB,MAAmB,WAEpC,qBAEA,YAGA,oBAAsB,MAAmB,OAMzC,iFAGA,iEACA,cAEA,CACA,SAEA,kBAEA,IAEA,GAEE,iCAMF,kDACA,QACA,2BAEA,SAGA,GAGA,SADA,YChrBA,CCMA,sBACA,QACA,MAEA,eACA,UAEA,aACA,OACA,UACA,KAEA,WAEA,SAEK,QACL,SAEA,UACA,CACA,QAEA,CCYA,gBACA,6BACA,8BAEA,+BACA,OACA,gCACA,OAEA,WACA,gBAEA,qBACA,QAEA,iBADA,UAEA,EAEA,sBADA,YAGA,CC0PA,gBACA,UACA,yBACA,yBAIA,IACA,QAEA,CACA,cACA,iBACA,sBACE,OACF,EAGA,CACA,gBACA,oBACA,+BAEA,oBAEA,iBAAiB,EAAa,IAC9B,0BAGA,QACA,OAIA,CACA,kBACA,CACA,UACA,UACA,QACA,OAiCA,CACA,kBAEA,yBAEA,+CAEA,4BAEA,kCAEA,WAEA,OAEA,eAEA,eACA,CAWA,CACA,gBACA,yBACA,oBAEA,+CACA,iBAeA,CACA,gBACA,oBACA,0BAIA,2BACA,gBAGA,CACA,kBACA,eAEA,+BAGA,8BACA,oCAGA,mCACA,kBACA,+BACA,yBAEA,CAEA,KACA,KAKA,CACA,KAEA,KAEA,sBACA,QAGA,CACA,gBACA,WACA,mBAEA,uCAEA,mCAIA,6BACA,MASA,CACA,kBACA,UACA,sBACA,wBAEA,sCAEA,qBAEA,mBACA,+BAEA,QAOA,CACA,gBACA,IACA,QACA,KAEA,EACA,UACA,QAGA,iBACA,UAIA,gBAEA,OACA,gBAEA,OAIA,SACA,kBAIA,QACA,SACA,QAKA,iBACA,uBACA,qBAEA,oBAGA,QACA,UACA,QAKA,kCAEA,MACA,gCACA,8BAGA,MACA,UAIA,mBACA,gBAEA,OAGA,wBAEA,IACA,IAKA,cAAqC,MAA6C,WAOlF,mBANA,UAOA,SAIA,UAGA,OAEA,8BAMA,cACA,UAGA,sBACA,IAEA,UAEA,eACA,UAGA,sBAEA,KC7mBA,CAkGA,oBACA,WACA,WAEA,kCAEA,WACA,cACA,kBACA,kBCTA,gBACA,WACA,uBAEA,YACA,0DAGA,MACA,0DAGA,IACA,IAmbA,gBACA,aAuCA,SACA,kBACA,2BAGA,4CACA,KACA,eACA,SA9CA,WAGA,wCAIA,OAEA,iBAEA,qBAAiB,MAAkB,WACnC,WACA,8BAIA,KAGA,YACA,OAGA,IACA,IAGA,UACA,UAIA,CAIA,MAFA,MAcA,CACA,aACA,SAGA,OAGA,6BADA,KCnmBA,CCuGA,aAEA,YAEA,iDACA,mBACA,SACA,sBACA,GACA,qCAEA,eACA,EAAG,UAEH,QAaA,CACA,sBACA,8BACA,eAEA,+BAIA,qBAGA,8CAMA,oFAGA,gBAGA,iBAEA,iCAEA,aACA,+DACA,iBAIA,4BAEA,mBACA,iBAEA,+BACA,CACA,OACA,QACA,QAEA,kBAEA,MAfA,2DAgBA,CACA,OACA,QACA,QAGA,mBCxLA,gBACA,cACA,KAGA,oCACA,0BACA,6BAEA,QACA,MAEA,QAEA,CACA,QCNA,CAqvBA,gBACA,UAIA,WAIA,yDACA,OAGA,CACA,gBACA,+BAAkD,gBAClD,+BAIA,SAGA,wBADA,SChxBA,CA8qBA,cACA,yBACA,kBAGA,gBACA,IAEA,CACA,kBAIA,QACA,sBAGA,sCAIA,aAIA,8BACA,wDAEA,yBACA,UAEA,oBACA,EC3rBA,CA2qBA,kBAEA,oBACA,aAGA,cACA,SAGA,WACA,WAGA,oCAEA,qBACA,MACA,IAEA,QAEA,SAEA,CACA,QChtBA,CC2bA,cACA,WAEA,cACA,WACA,kBAEA,6BACA,OAEA,CACA,QAQA,CACA,gBACA,QAEA,UACA,IAEA,OACA,WAEA,SACA,OACA,UACA,CACA,iBAGA,OAEA,MACA,WAEA,SACA,OACA,UACA,CACA,iBAGA,OACA,CACA,CC7eA,CCRA,cACA,kBACA,kBCgBA,CAwOA,cACA,oDACA,ICpPA,CCRA,cACA,OAEA,WACA,QAGA,IACA,QCQA,CCoDA,cACA,yCACA,UAUA,CACA,cACA,2BACA,KAWA,CACA,cACA,OACA,cAEA,YAEA,IAEA,CAaA,gBACA,UAGA,6BACA,aAGA,YACA,cAOA,CACA,cACA,MACA,aAEA,CACA,gBACA,4BACA,+CAEA,6DACA,yBACA,iCAEA,mBACA,oBAEA,EACA,CACA,CClJA,CACA,kBAEA,cAkCA,qCAEA,qBAEA,kBAGA,IACA,yBAIA,IACA,OAIA,mBAGA,eACA,UAGA,0BACA,OACA,IAEA,cAGA,SACA,QAEA,mBAnEA,OACA,MAGA,QAGA,uBACA,MAEA,KACA,IAGA,MACA,WACA,QACA,QACA,WAGA,mBACA,WACA,SAGA,IAEA,KAEA,WAsCA,EAGA,IAEA,OAAe,GAAW,IAC1B,SAIA,WAAsB,IAAW,IACjC,SAKA,UAEA,KACA,GAAE,OAIF,4BACA,ECvGA,CACA,kBACA,mCACA,KCLA,CACA,cACA,WAGA,gBAEA,cCYA,CAuqBA,cACA,IACA,2CAGA,oDAEA,8BACA,yCCtrBA,CCVA,cACA,OAEA,SACA,qBACA,gBAGA,IACA,QCLA,CACA,cACA,MAGA,+BACA,iBACA,eAGA,WACA,QCbA,CACA,gBACA,SACA,QAEA,YAGA,mBACA,MAGA,yBACA,ECIA,CAsiCA,kBACA,OAGA,wCAGA,gDACA,eAMoB,CACpB,gBACA,eACA,UACA,SAEA,UCnlCA,CC8GA,cACA,cACA,kBACA,iBACA,eACA,SC9GA,CACA,cACA,OACA,oDCHA,CACA,cACA,OACA,qDCGA,CCJA,cAEA,qCAEA,0BACA,+BACA,sCACA,wCACA,oCAEA,ICPA,CA2WA,gBACA,UACA,cAEA,IAMa,CACb,cACA,SAIA,2BACA,ICrXA,CACA,YAA6C,2BAA6B,GAC1E,SACA,aACA,OAGA,QACA,IAQA,KACA,KAEA,MAIA,WAMA,IAKA,iBAEA,QAEA,YAKA,YAKA,UAJA,iBAEA,OAGA,CAOA,CAyDA,kBACA,0BACA,0BACA,gBAEA,kCAEA,gCACA,IAAO,WAEP,aACA,mBACG,MACH,wBAKA,UACA,oBACG,OACH,uBAGA,WACA,aACA,CAMoB,CACpB,gBACA,SACA,gBAEA,gBACA,QACA,gBAEA,gCACA,cACA,6BACI,IACJ,kCAGA,QACA,+BACI,KACJ,kCAIA,YAEA,UAMsC,CACtC,gBACA,mBACA,MAMsC,CACtC,gBACA,gBACA,GAMsC,CACtC,gBACA,iBACA,IAMsC,CACtC,gBACA,kBACA,KAMa,CACb,cACA,OACA,sCAEA,4BAEA,WAMa,CACb,cACA,UACA,SAGA,wBAKA,wBAJA,gBAGA,aAEA,UAEA,UAQa,CACb,gBACA,SACA,QAEA,aACA,MAEA,gBAEA,WACA,WACA,yBAEA,gDAEA,SACA,MAGA,CACA,QC3PA,CCfA,gBACA,cACA,WACA,eAEA,OAEA,sBACA,qBAGA,iCAEA,wBACA,iCACA,aACA,QAEA,EACA,CCrBA,CACA,aACA,kBACA,WAEA,gBAIA,yBAIA,8BAEA,+CACA,kBACA,4CACA,WACA,EACA,CAyBA,CACA,aACA,kBACA,WAEA,eAIA,yBAIA,wBACA,8BACA,uBAEA,mCACA,2CACA,aACA,CAiDA,CACA,cACA,kBACA,SACA,kBACA,wBAEA,eAIA,sCAEA,qBACA,qBACA,CAYA,CACA,cACA,kBACA,SACA,qBAGA,WAIA,QACA,YAGA,oBACA,6BAEA,4BACA,qBACA,CAEA,CACA,sBACA,OACA,YAGA,aACA,aAGA,eAMA,wBACA,qDAIA,oBAEA,oBACA,6BACA,aAEA,cACA,UACA,WAGA,0BACA,uBACA,aAIA,SACA,QAyBA,CACA,aACA,kBACA,gCAEA,cAEA,0BACA,+BAIA,uBACA,iBACA,CAKA,CACA,aACA,kCACA,WClPA,CChBA,cACA,oBACA,uBAGA,QACA,SCPA,CACA,gBACA,aACA,yBAGA,WACA,WCDA,CCiMA,cACA,qBACA,mBC5LA,CCk8BA,cAYA,gBACA,YAGA,aACA,cACE,YAKF,iBAQY,CACZ,gBACA,cAEA,KACA,kBAMA,cAOgG,CAChG,gBAAiD,CAAO,QACxD,OAMA,yBACA,kBAEA,eAGA,IACA,QAEA,WAEA,MAOa,CACb,cACA,OACA,OACA,GACA,aAEA,UACA,eACA,EAEA,EASa,CACb,kBACA,OACA,OACA,GACA,qBAEA,UACA,GACA,sBAEA,EAQa,CACb,gBACA,OACA,OACA,GACA,UAEA,UACA,YACA,IAEA,EAKa,CACb,cACA,mBAYA,uCACA,OAEA,QAEA,GACA,QAWmD,CACnD,cACA,IACA,qBACE,QACF,MAGA,QACA,2BAGA,aAGA,YACA,GACA,iBAGA,iBAEA,WACA,iBACA,mBAEA,gCACA,uBACA,QAEA,eAMA,aACA,UAEA,CACA,QAsBkB,CAClB,cACA,UACA,aACA,kCAGA,QAEA,OAmBoB,CACpB,cACA,UACA,QAGA,QACA,QAWmD,CACnD,cACA,OACA,MAEA,IAgBiD,CACjD,cACA,iBACA,kBAEA,MAiBkB,CAClB,gBACA,eACA,cAEA,MAOa,CACb,gBACA,OAEE,SAGF,QAAY,IAAU,KAEtB,EAea,CACb,gBACA,UACA,QACA,kBAEA,WAGA,IAMiD,CACjD,gBACA,MACA,gBACA,eAGA,iCAGA,eACA,oBACA,mBAGA,yCAGA,mBACA,uBAGA,oCACA,kCAMA,YACA,QAIA,6GAEA,mBACA,uBAEA,OACA,CAMa,CACb,cACA,WACA,KAKa,CACb,cACA,OACA,gBAKa,CACb,cACA,OACA,gBAKa,CACb,cACA,OACA,gBAKA,CACA,aACA,OACA,CACA,YACA,YAEA,cAMkB,CAClB,cACA,mBACA,UCt1CA,CCjEA,cACA,0CACA,IACA,iDAGA,aACA,aAEA,OACA,KCmDA,CACA,YAAqC,0CAAqD,iBAG1F,CACA,UAKA,KACA,UAGA,kBACA,iBACA,YAEA,aACA,GAGA,SACA,cACE,YACF,sBACA,4BAEA,QACA,MAGA,oBACA,OAEA,IAAM,QAAY,OAElB,WACA,YACA,aAMA,WACA,UAOA,SACA,gBAOA,eACA,UACA,GAEA,OAAS,cACT,OAQmB,CACnB,kBACA,MAAQ,cAAkB,QAE1B,0BACA,YAYmB,CACnB,sBACA,OACA,IACA,EACA,EAGA,YAEA,6BACA,aA+CA,CACA,IACA,IACA,IACA,GAIA,YAtDA,aACA,GAEA,EACA,UAEA,WAKA,yBAEA,uBAEA,CACA,UAKA,sCAIA,2BACA,GACA,KAIA,IACA,MACA,KAKA,SACA,KACI,UACJ,KAIA,IAUA,KAEA,WACA,IAOoB,CACpB,YAAsC,QAAY,OAClD,MAAQ,WAAmB,cAE3B,aACA,MACA,QAEA,IC/OA,CCwVA,cACA,OAIA,SACA,QAGA,wBACA,wBAGA,KACA,IAiBA,CAiUA,gBACA,0BACA,mBAOa,CACb,cACA,oBACA,mBCrsBA,CACA,cACA,WAEA,gBACA,KAGA,OACA,KCMA,CCkQA,cACA,mBACA,sDClRA,CCgBA,cACA,+BACA,cACA,WAEA,gBACA,EChBA,CCSA,cACA,cACA,WACA,CAKA,yBAMA,CAEA,aAPA,CAIA,SCpBA,CAiPA,cACA,YAEA,0BACA,GACA,sBACA,0BACA,0BACA,sBACA,0BACA,yBACA,GACA,sBACA,0BACA,0BACA,sBACA,0BAEA,wBC1PA,CAyGA,cACA,cACA,aClHA,CACA,YACA,CACA,SACA,yBACA,qBACA,UACA,cACC,aAGD,SAGA,gCACA,8BAEA,eAGA,MAEA,QAEA,IAGA,iCACA,gBACA,cAGA,WAGA,IAEA,IACA,EC9CA,CC8CA,cAEA,8BACA,iCAEA,mBAIA,SACA,cACA,4BACA,YCxDA,CAmCA,gBACA,kBACA,kBACA,YACA,WAGA,mCACA,6BAGA,2BACA,kBACA,yCACA,eAIA,+BAEA,8BAEA,eC9DA,CACA,cACA,CAuBA,SArBA,eACA,qBAGA,wBACA,yBAEA,mBACA,wBAEA,0BAEA,YAEA,2BAAe,OAMf,SCxBA,CACA,cACA,OACA,qEAGA,OACA,YAKA,MCfA,CASA,cACA,OAEA,yBAEA,iBACE,yCAEF,wBACE,WAGF,OAEA,oCACA,SAGA,yCACA,0DACA,SAEA,QAIA,QACA,KACA,GACA,CAEA,CACA,QCsDA,CCnEA,oBACA,WACA,gBACA,0BACA,eAGA,+CAKA,MAOA,eANA,QAGA,oBAIA,cACE,WACF,oCACA,6BAEmD,CAOnD,sBAPA,cAaA,SAGA,kBACA,EAEA,kBACA,WACA,oCAEA,mBAIA,kCACE,aAIF,qCAEA,aAGA,mCACA,YCrFA,CCeA,gBACA,aA4CA,OACA,UAEA,KAEA,cACA,aACA,OACA,MAnDA,YACA,EAEA,EAsCA,sBArCA,CACA,YAEA,IACG,KACH,eACA,wBAEA,OAEA,MACA,MACA,SACA,gBAIA,QAEA,OACA,YAEA,WAEA,MACA,MACA,SACA,gBAIA,GAEA,GAEA,KC7CA,CCsTA,cAEA,WAIA,uBACA,QAGA,CACA,gBACA,yBACA,2BAEA,KAEA,KAKA,CACA,cAEA,IAKA,yEACA,yBAGA,kBAIA,uBAGA,mBAKA,0BAQa,CACb,cACA,SACA,aACA,aACA,6BAAmD,CASnD,0CAA2B,gBAC3B,0DACA,sBAUa,CACb,cACA,IACA,YAIA,kBACA,iCACA,MAIA,SACA,QAKa,CACb,cACA,0BACA,QAMa,CACb,cAEA,OAEA,OAGA,eAAiB,MAAuB,WACxC,SAEA,KACA,eACA,YAEA,IAGA,OAEA,IAEA,SAA6B,KAAmB,KAEhD,IACA,gBAIA,IACA,gBAIA,UAAS,0BACT,gBC3cA,CCiJA,gBACA,YAKA,kDAGA,aAAiB,MAAwB,WACzC,aACA,KAEA,wBAEA,iBACA,eACA,GAEA,IAEA,CACA,QAEA,CACA,gBACA,UACA,yBAGA,qBAAmB,MAAmB,WAEtC,IAEA,YACA,UACA,gBACA,6BACA,iBAGA,cAEA,UACA,WACA,aACA,kBACA,wBACA,iBACA,iBASA,8BAGA,mBAEA,EAIA,CACA,QCxNA,CCGA,aACA,OAEA,OAMA,YALA,eACA,OAGA,WAQA,CACA,cACA,KACA,4CAEA,sBACA,iBACA,sCAEA,kBACA,kCAEA,GAEA,OACA,KAOA,CACA,gBACA,iEACA,SAMa,CACb,cACA,OACA,cAEA,6BAEA,6BAAiB,MAAuB,WACxC,2BACA,+BACA,eAEA,CACA,QChEA,CCwMA,cACA,2DACA,GC1MA,CCmZA,aACA,OACA,OCnVA,CAwaA,oBACA,SACA,UACA,QAGA,YACA,MAEA,sBACA,6BAEA,aACA,cACA,QACA,sBAGA,kBACA,iCAEA,MAMA,CACA,aACA,OACA,OCpgBA,CCqKA,cACA,4CACA,IASa,CACb,cACA,OAEA,EADA,OAGA,uBACA,SACA,WAGA,YAGA,sBACA,oCACA,mBAGA,MACA,GAEA,CACA,QAEA,CACA,gBACA,iBACA,MACA,uBAEA,4BACA,QACA,6BACA,2BAGA,qBACA,KCtNA,CCkMA,oBACA,IACA,qBACA,uBAEA,KAEA,eAAuB,MAA4B,YACnD,mBACA,eAEA,kBAAmB,MAAkB,OACrC,WAGA,wBACA,eAEA,mBAAgC,CAChC,QAAE,SACF,iBACA,2CACA,CAQA,CACA,cACA,IACA,mBAGA,mBACA,wBACA,OCnPA,CCgBA,aACA,kBAEA,mBAAsC,eAKtC,0BAAqC,0CAKrC,kEAGA,8CAAuF,CAKvF,qBAIA,6BAEA,oCAEA,qBAGA,mBAGA,iBACA,UACA,CASA,CACA,qBACA,UACA,aAAiC,iBAAgB,SACjD,UAAoC,oBAAgB,SACpD,UAAoC,oBAAgB,SAEpD,IAMA,CACA,aACA,kBACA,sBACA,kBACA,OAEA,UAIA,+BACA,8BACA,OAEA,2BACA,WAEA,oBACA,yBACA,4BAEA,WACA,yBAGA,SAAG,KACH,WAEA,oBACA,iCAEA,6BAEA,WACA,gCAGA,OACA,EACA,CAIA,CACA,aACA,kBACA,sBACA,kBACA,OAEA,UAIA,+BACA,8BACA,OAEA,GACA,yCAEA,8CAEA,mBACA,CAEA,CAWA,oBACA,WAGA,kBAA8B,SAO9B,gCAA8C,cAAuC,gCAErF,QAKA,qBACA,eAEA,qBAGA,4BACA,SAWA,CACA,kBAEA,KAIA,oBACA,QACA,kBACA,WAIA,iCACA,WACA,+BAGA,iBACA,aAEA,KAIA,mBACA,IAiBA,CACA,gBAEA,MAOA,oBAKA,iBAIA,oCAA0C,EAAQ,SAClD,kBAEA,yBAoBA,+BACA,QAGA,KACA,iBACA,qDAIA,SAIA,WAIA,aAIA,aAGA,WACA,mCAEA,OACA,CAGA,GACA,kBAEA,WC7SA,CA8GA,gBACA,wDACA,MAMa,CACb,gBACA,iBACA,SACE,8BAKF,4BACA,MAMa,CACb,cACA,uCACA,MCpJA,CAyBA,cACA,WACA,qBAeA,CACA,cAA+C,KAC/C,cAmBA,2BACA,GACA,CAHA,wCAjBA,WACA,qBACA,eAEA,2BACA,cAGA,OAEA,8BACA,oCAGA,UAeA,CACA,kBACA,SAEA,gCACA,GACA,qBAGA,iBACA,qBAEA,cAEA,+CACA,uDACA,UASA,CACA,gBACA,GACA,uBAOA,CACA,cACA,WAGA,oDAIA,MADA,EAYA,CACA,cACA,CAmBA,kBAhBA,qEAGA,0CACA,4CACA,OAEA,oCAEA,cAEA,qCAEA,sBAEA,IAKa,CACb,aACA,OACA,KC1JA,CAWA,gBACA,UAEA,8BAAgC,CAEhC,gBACA,oBACA,oBAEA,gBAAsB,IAAa,KACnC,IACA,GAOA,CACA,cACA,kCACA,KAOA,CACA,cACA,WAEA,iCACA,MAQA,CACA,cACA,yBACA,eCxCA,CAqFA,aACA,wBAA+C,OAAiB,gBAChE,OC/FA,CC8UA,cACA,cACA,kBACA,iBACA,eACA,SAKa,CACb,cACA,4BACA,SAKa,CACb,cACA,OACA,UAKa,CACb,cACA,SACA,uBACA,iBAGA,aACA,MAEA,CACA,QCtXA,CCUA,YAA8C,kCAAgD,mBAC9F,oCAAkD,CAAS,YAC3D,IAIA,cACA,aACA,YAIA,OACA,IACA,ECzBA,CC6BA,YAAwC,CAAO,QAC/C,sCACA,GACA,wBACA,SAAE,EAAG,CACL,eC7BA,CCDA,cACA,uBAEA,qDACA,SAEA,QACA,iBACA,CASA,CACA,cACA,mBACA,UAEA,uBACA,6CACA,gCACA,GACA,kBAGA,kBC/BA,cACA,SAEA,8CACA,KAgBA,CACA,cACA,WAEA,qBACA,eAGA,oDAEA,WAGA,MACA,kBAGA,uBAGA,8BAKA,mBACA,eAEA,UACA,KC9CA,CAkKA,cACA,mDACA,2BClJA,CCoFA,aACA,sBAA4C,OAC5C,oBAGA,SADA,0BAQa,CACb,cACA,kBACA,mBACA,sBAGA,QCzHA,CCmDA,gBACA,gBACA,MACA,sBAEA,iBCrDA,CA4HA,oBAEA,mBAAqC,cAKrC,+BAKA,2BACA,qCACA,qBAEA,QACA,SAMA,CACA,oBAEA,OACA,OAGA,wEAYA,WACA,aACA,wDAGA,iBACA,GAIA,2BAGA,+BAIA,cAMA,eAAiB,aAA4B,eAC7C,kBAEA,6BAGA,aASA,cARA,uCAKA,YAIA,WAIA,qBAEA,IAGA,cAEA,MAEA,oBACA,iBAIA,0BAAoD,QAKpD,wBAAsB,kBAKtB,sBAAsB,wBAKtB,cAEA,CAGA,gBACA,iCACA,WAEA,aACA,YACA,WAGA,YAEA,SACA,CAEA,CACA,aACA,qBAIA,WAEA,aAGA,SACA,MANiB,yBACjB,4BAOA,IAGA,yCACA,aAEA,EACA,CC5RA,CA2EA,kBACA,gBACA,CACA,iBAEA,iBCpFA,CC4BA,gBACA,SACA,8EAEA,cAEA,gBACA,cCIA,CACA,gBACA,SACA,qBAEA,UA8CA,0CA7CA,SAGA,UAGA,iCADA,OAIA,+BAEA,2BAEA,qCAEA,GAEA,sBAEA,SAGA,sBACA,GACA,SAIA,uCACA,GACA,WACA,QAEA,IAIA,qCACA,GACA,WACA,YAEA,IAEA,IAOgE,CAChE,cAGA,gCAAuD,CAAuB,YAE9E,yBACA,gBAEA,UACA,GCQA,gBACA,6CAIA,OAkEA,CCzKA,kBACA,WAEA,YAMA,gBAIA,qFAGA,SACA,qBACA,uCAAmF,UAKnF,yBAGA,gCAGA,SACA,OAMA,CACA,cACA,WAEA,uBACA,oCAEA,uBACA,kBAEA,SAKgD,CAChD,cACA,YAEA,gBACA,UAEA,OAMoB,CACpB,gBACA,WAGA,SAIA,gBACA,cAGA,cACA,IAOA,0BALA,uEAQA,uBACA,6BAMA,+BACA,sBAEA,gCAEA,mBCnHA,CASA,gBACA,WACA,gBACA,uBACA,aACA,yBAEA,QACA,KACA,CAiBA,CACA,cACA,kBACA,kCACA,kBAIA,eACA,KASA,CACA,cACA,WAGA,mEACA,SAAU,CAGV,SACA,IChDA,CA8GA,oBACA,IAGA,6BACA,cACA,MAEA,uCACA,WACA,qCACA,qCAGA,CACA,4CAEA,WAEA,EACA,EAMY,CACZ,mBACA,kBACA,WAEA,WAGA,6BACA,sBACA,UAEA,oDACA,sCAEA,MACA,uBAEA,6BACA,OACA,CACA,CAOkD,CAClD,oBACA,uBACA,UACA,cACA,iBAMA,CACA,cACA,wBAAyC,CACzC,+BACA,uCAGA,yBACA,I,CClMA,cACA,kBACA,2BACA,OAEA,0BAKA,sBACA,4BACA,gDAEA,QACA,YAGA,WACA,mBAEA,QACA,CAOA,CACA,cAEA,0BAEA,4BACA,UACA,QAEA,WACA,CAQkB,CAClB,oBACA,WACA,UAIA,mBAA4C,SAK5C,aAKA,wCAEA,6BAAoC,+BAKpC,6BAAyC,SACzC,0CACA,OAMY,CACZ,gBACA,UACA,aACA,SAGA,QAQqB,CACrB,kBACA,kCACA,wCAMA,cAQqB,CACrB,kBACA,+BACA,qCAMA,eCoEA,cACA,YACA,mBAEA,gBAGA,mBACA,cAAoC,UAGpC,oFAA4F,CAE5F,WAAqB,CAKrB,2BACA,aACA,eACA,sBACA,UACA,yBAGA,MACA,GAGA,CAIA,mCAHA,mBAEA,QC5NA,CCCA,gBACA,0BACA,WAQmD,CACnD,kBAGA,qCAEA,aAEA,4BACA,gBACA,4BAGA,8CACA,UC1BA,CCsSA,cACA,mCACA,gBCzSA,CA0PA,kBAEA,2BAEA,WACA,4CAcA,gCAIA,8CACA,+BACA,6BAIA,0BAEA,4BAGA,mCAGA,cAOa,CACb,gBACA,gBACA,MACA,WACA,uCAEA,iBC9SA,CAuIA,gBAEA,SAGA,SACA,KAMA,mDAJA,iBAQA,mDAEA,QAGA,CACA,gBACA,6BAIA,4FACA,6CAEA,UAGA,6BACA,kBAEA,OACA,KC3KA,CAsBA,aACA,sDAEA,sDACA,ICVA,CACA,oBACA,kBACA,yBACA,oCAKA,yCACA,2BACA,sCAEA,iCACA,cAGA,qCAEA,0BACA,UAaA,CACA,oBACA,sBACA,wBAGA,wCAIA,2BACA,sCAIA,wBACA,oDACA,UAGA,mBACA,kBACA,kBAUA,CACA,oBACA,sBACA,UAGA,uCACA,4DAEA,iBAIA,+BACA,sCAGA,0BACA,WACA,qBACA,eAEA,eACA,oBAIA,6EAIA,QACA,kEAEA,KAUA,CACA,oBACA,sBACA,0BAGA,wCAIA,2BACA,sCAGA,0BACA,WACA,qBACA,eAGA,aAEA,QACA,uBAIA,sBAIA,0DAGA,sBACA,SA0BA,CACA,oBACA,4BACA,uCAEA,YAgDA,iCACA,4BAEA,kBAMA,4BACA,4BAGA,wBACA,mBACA,eACA,OAEA,oBAIA,sBACA,WAAmB,MAAkB,WACrC,WACA,yBACA,aAGA,QACA,gBAIA,kBACA,aAEA,QACA,CAGA,mBACA,UACA,CACA,CAwBA,CACA,oBACA,2BACA,mCACA,oBACA,eAKA,UACA,OACA,CAcA,CACA,oBACA,sBAAuC,CAAa,UAEpD,gBAGA,uCACA,4BAGA,qEACA,0BAGA,oBAGA,UAGA,iBACA,SAKA,uDAEA,WAIA,iCACA,2CAIA,wCAEA,SAEA,GACA,mBAEA,QACA,QACA,CAWA,CACA,kBACA,mBAAoC,CAAa,UAEjD,4BAEA,wBACA,aACA,SAGA,QACA,CASA,CACA,kBACA,mBAAoC,CAAa,UACjD,IACA,uBAGA,2BAEA,kBACA,MAEA,cACA,6BACA,SAGA,cAGA,0CAIA,+DACA,sCAEI,wBAEJ,SAGA,MAEA,IACA,CAUA,CACA,gBACA,yBAEA,kCACA,kBACA,+DACA,gBACA,6BAGA,cACA,mDACA,kBAEA,iBACA,KAAI,yCACJ,kBAEA,aACA,KAEA,CACA,CAUA,CACA,gBACA,WACA,iBACA,WAEA,qCAEA,eAGA,4BAEA,8BACA,eAAG,KAKH,4BACA,iCAGA,+CACA,eAEA,GACA,MAAE,wFAGF,WAIA,wBACA,MAEA,qCACA,aAEA,sBAGA,mDAEA,kBACA,MACA,CAkBA,CACA,cACA,kBACA,IAIA,qCACA,0CACA,6DAIA,YAEA,UACA,YAAG,mBACH,0CACA,6DAIA,YAEA,UAIA,wBAEA,sBAIA,yBAEA,oBACA,WAAG,mEACH,WAGA,6BACA,iDACA,OAEA,4BAIA,SACA,SAAG,KAGH,yBAEA,sBAIA,yBAEA,oBAEA,YACA,CAGA,CACA,kBACA,SAEA,aACA,yCACA,WAEA,iEAGA,uBACA,iBAEA,8DACA,kBACA,6BAGA,kCAEA,mBAAiB,QAEjB,eACA,WAEA,IAEA,4BACA,2CAGA,OAEA,EAIA,CACA,oBACA,wBAEA,kCAOA,mDACA,cAEA,UAMA,gCACA,2BAEA,4CACA,wDACA,+BAGA,kCAEA,cACA,EAwBA,CACA,oBAMA,2CAEA,4BAEA,WACA,yBAEA,oBACA,gBACG,qCACH,kBAIA,cAIA,wBAGA,aAEA,iBACA,oDAEA,iBAGA,WACA,CACA,CAIA,CACA,gBACA,iDACA,OAEA,kBACA,MAKA,SAHA,oBAEA,mBAaA,CACA,gBACA,iCACA,0CACA,mBACA,uBACA,iBACA,mBACA,oBAEA,sDACA,sCAEA,4BACA,wBAEA,UACA,MACA,SACA,QACA,IACA,iBACA,iBAEA,WAEA,KAEA,QAEA,IACA,SAGA,QACA,IAEA,OACA,KAGA,CACA,gBACA,sDACA,2BAGA,gBACA,IAKA,CACA,oBACA,WAGA,kBAKgD,gCAEhD,sBAFA,2DAKA,WACA,wCACA,eAEA,UAEA,qBAMA,2DAEA,yCAIA,uCACA,SAQA,wCAIA,mBAGA,SAOA,oBAEA,KAAG,wCAGH,gBACA,WAGA,sCAGA,2CAEA,UACA,aACA,wCACA,kBAEA,4BACA,UACA,SAGA,QACA,kBACA,kBAGA,CACA,sBAKA,cACA,CACA,cACA,iBACA,oBAIA,wCAEA,QAEA,MAiBA,GACE,iBAkBF,4BACA,YACA,cAAE,KAmBF,uBACA,WACA,iBAEA,GAIA,0BACA,iCACA,qCAEA,WACA,kBAGA,mBAEA,CACA,gBACA,wBACA,gCAEA,iBAEA,uDACA,gBAEA,oBACA,eAIA,KACA,QAMA,CACA,cACA,iDACA,aCz/BA,CAyFA,cACA,OAEA,mBACA,+BACA,8BACA,iBAKA,MACA,uBnJ6ZA,sCoJrgBA,wDCjCA,WACA,cAQA,eCHA,GDIA,WACA,WACA,UAEA,EESA,GDhBA,WAGA,IACA,kBACA,iCACA,QACA,GAAK,UAEL,CACA,QAEA,EEdA,GDmBA,WACA,YACA,kBAEA,YCjBA,gCAGA,eAGA,0BAOA,cA8BA,SCzCA,GD0CA,WACA,KACA,mBAjDA,mBAkDA,MAEA,eACA,SACA,SAEA,2CACA,kBACA,yCACA,WAEA,ECvDA,QAOA,iBAOA,MAIA,mBAKA,0CAEA,UAuCA,SACA,wBACA,YAaA,YAGA,wBACA,eAcA,OACA,iCACA,UAYA,yBAEA,IACA,MAMA,iBAJA,0CAOA,SAGA,eAEA,WACA,QAIA,WAIA,WAEA,WACA,QAGA,WAGA,eAMA,mCAIA,2BACA,QAUA,oBAEA,iBAGA,SAGA,uBACA,cACA,GACA,KACA,KAGA,GACA,IAGA,UACA,WAUA,0BACA,6BACA,uBACA,OACA,EACA,EpM5MA,KACA,IAWA,sGACA,sBAaA,iBACA,GAGA,qBAGA,cAKA,mBAOA,qBACA,MAQA,0BACA,OACA,gBAQA,EC/BA,SAWA,WACA,eACA,OAYA,WACA,cACA,OAGA,MoM7DA,OACA,QAWA,oBAKA,MAQA,oCAMA,sBAEA,cACA,+BAEA,WACA,yCAGA,aAKA,qBACA,qBACA,SACA,0BAGA,QAQA,OACA,sBACA,MAcA,aACA,cA6CA,UAKA,yBAIA,cACA,gBAqBA,CAGA,gFAHmF,CAEnF,YAEA,EAEA,cACA,yBACA,GAEA,SACA,kCACA,SAEA,UAQA,iBAGA,kIAAS,UAIT,eACA,IAGA,WACA,WACA,YAEA,QACA,GACA,EAEA,cACA,OAIA,2CACA,MAEA,cAaA,OACA,YACA,mBACA,GACA,SA7IA,YACA,aACA,KAEA,OACA,OACA,kBAuHA,MAEA,eACA,QACA,QAIA,0BACA,IAEA,CAhIA,SAwBA,SAGA,+GAAyB,CAEzB,oCAAwD,CACxD,YAEA,sBACA,aAEA,MAyGA,UACA,oBACA,WACA,sBACA,yCAEA,0BACA,MASA,UACA,eAEA,mBAMA,6BAWA,UACA,KACA,qFAAK,uDAGL,0BAEA,SC7QA,EACA,QAIA,cAOA,mBACA,IAQA,SACA,gBACA,QAQA,OACA,uBACA,MAOA,gBACA,cAEA,UAOA,+EAA6F,CAG7F,0BACA,KAOA,SACA,sBACA,MAOA,YACA,sBACA,QAKA,oBACA,8BACA,WAKA,UACA,qBACA,aAEA,SACA,EpM7FA,GAmCA,OC9BA,QAMA,eAOA,cAqBA,4BACA,KAOA,QACA,cAGA,QAMA,iCALA,kBAIA,UClCA,KmMjBA,IlMIA,UACA,oBACA,GACA,SACA,CAEA,EkMTA,QAKA,iBAOA,MAQA,cAQA,YASA,kBAOA,cAkBA,IACA,EhM1DA,SAQA,OACA,OACA,mCAIA,MAEA,EACA,YACA,gBACA,MACA,YC7BA,MAEA,gBACA,yBAQA,gBA4BA,QAAkC,KAClC,GACA,kBACA,mBAEA,YACA,CACA,WAIA,6BAEA,IAEA,gBAAmB,MAAsB,OACzC,uBACA,YACA,KAEA,KACA,KAKA,MAEA,OACA,CAcA,aACA,MAUA,qBARA,GAGA,oBACA,KAGA,IAUA,UACA,WAEA,iBACA,kBAAmB,MAAsB,OACzC,SAEA,yBACA,GAIA,IAcA,mBACA,OAgBA,EACA,WAGA,qBAEA,SACA,MAGA,aAEA,QACA,eACA,CACA,UAIA,oBACA,oBAGA,mBAGA,UACA,SAiBA,sBACA,SACA,kBACA,mBACA,eAGA,6BAKA,OACA,OAGA,mBACA,UACA,SAEA,kBACA,YAEA,WACA,YACA,eAEA,yBACA,KAEA,KACA,CACA,mCAEA,eACA,SACA,CAeA,cACA,kCACA,YACA,aAGA,uBAGA,QAEA,YAOA,cAEA,kBAAmB,MAAsB,6BAIzC,cAEA,sBAEA,uBAIA,mBAIA,QAfA,KAkBA,sBACA,2BACA,+BAGA,QAIA,YAEA,QAEA,UACA,MAoBA,gBACA,OACA,WACA,MACA,oCAGA,uBACA,2BAGA,WAIA,0CAFA,QAGA,CAEA,EAcA,qBACA,SAIA,gBACA,qBACG,gBACH,qBACG,cACH,2BAGA,YAEA,SACA,CACA,MAYA,OgM9XA,G/L6BA,aACA,sBACA,KAEA,Y+L9BA,gBAWA,eCNA,GDOA,eACA,OACA,mBACA,sBACA,UAEA,OAEA,EEpBA,GDMA,iBACA,KAEA,iBACA,MAEA,cACA,OAEA,OACA,SACA,YAEA,KACA,SACA,CACA,QAEA,EEjBA,GDNA,WACA,mBACA,uBACA,IACA,CAEA,QEWA,UCrBA,GDsBA,WACA,OACA,kCACA,cAEA,YChBA,gBAmBA,SChCA,GDiCA,WAIA,wBACA,aAnCA,qBAoCA,GAjCA,4BAmCA,EEdA,GDEA,WACA,OACA,kCACA,GAJA,gBAMA,EElCA,GD4BA,WACA,6BACA,KAEA,KCpBA,mBCCA,GDAA,aACA,UACA,QAZA,oBAaA,4BACA,wBACA,GAEA,EEZA,GDMA,eACA,KACA,MAEA,eACA,iBACA,4BACA,wBAEA,aAGA,OAEA,EE1BA,GDOA,eACA,SAEA,sBACA,yBACA,0BACA,+BAEA,MACA,UAEA,YCRA,gBAmBA,SC3BA,GD4BA,WACA,OACA,8BACA,SA9BA,iBAgCA,OC9BA,KAGA,gBAGA,wBAGA,gBAGA,iBAwBA,SCzCA,GD0CA,WACA,IACA,mBAEA,YACA,MAEA,mBACA,uBACA,sBACA,IACA,IACA,kCAEA,kBACA,aACA,qBACA,0BACA,iBACA,EAEA,OCtCA,ECDA,GDEA,WACA,IACA,kBAEA,OACA,sBACA,cACA,QACA,yBACA,gBACA,CAEA,EtBrCA,GuBwBA,WACA,OACA,UAEA,uBACA,CAEA,QC1BA,GxByBA,aACA,IACA,8BAEA,WA/BA,+DAgCA,aACA,WACA,aACA,kBACA,KAEA,SACA,cAEA,KACA,+BACA,oCACA,uCAEA,qBACA,UACA,EACA,YAEA,WACA,aACA,OACA,CAEA,YyBtDA,aACA,WACA,YACA,sCAEA,oBACA,MAEA,OCdA,WAEA,QCCA,MhNFA,GgNGA,WACA,QAGA,MAFA,gBAGA,eAEA,OACA,QAEA,YhNVA,mBACA,uBASA,6BAY4D,iBAC5D,0BACA,WACA,MAGA,MiN3BA,MCmBA,GDlBA,aACA,YACA,IAEA,SACA,YAEA,KACA,QAEA,EEhBA,GDyBA,WACA,eACA,KAEA,YCvBA,gBAOA,qBAGA,eAmBA,qBCbA,GDcA,WAEA,yBACA,qCACA,SArCA,qBAuCA,WClBA,QCvBA,gBAUA,gBAmBA,SCpBA,GDqBA,WACA,OACA,sCACA,SA9BA,iBAgCA,EEjCA,GDQA,WACA,WACA,oBACA,uBACA,YAEA,QACA,IAEA,YCdA,gBAwBA,eCzBA,GD0BA,WACA,YACA,IACA,QACA,UACA,SACA,QAEA,UAEA,cACA,OACA,MALA,kBAMA,oCACA,cAEA,OACA,CACA,QAEA,YC3CA,gBAGA,4BAAgE,iBAiChE,cXrCA,WACA,wBACA,QACA,MACA,iBACA,kBAEA,4BACA,sBAGA,2BACA,UACA,eAEA,KACA,iBACA,OAEA,QAEA,UACA,CACA,QACA,ECjCA,eU+CA,eACA,MAGA,iBAFA,gBAGA,eAEA,KAEA,GCzDkB,MxNclB,gBACA,wBACA,8BAUA,sBAeA,SAEA,IACA,MAOA,wCANA,YACA,KAAI,EAEJ,QAKA,cAEA,0BAgBA,oBAGA,sGACA,CACA,cAEA,qBACA,UACA,MAEA,QACA,WAIA,gBACA,WACA,mBAEA,mBAGA,IACA,SAqBA,YACA,gBAMA,kBAGA,uFAMA,oBAGA,iEAEA,cAEA,wBACA,MAMA,oBAEA,yEAEA,cASA,2BACA,SAAoB,QAEpB,SACA,WACA,QAaA,GACA,CAEA,iBACA,KACA,aACA,OAEA,YAYA,cAEA,WACA,OAGA,eACA,WAEA,qBACA,KAMA,kBAGA,6EACA,WACA,iBAEA,oBAEA,KACA,OACA,OACA,SAEA,OAEA,YACA,YAGA,qBACA,WACA,+BAEA,UAEA,KACA,SACA,EACA,uBACA,sBACA,SAEA,KACA,UAEA,OA2DA,aACA,SAEA,WAQA,QACA,QACA,kFAAK,aAIL,gCACA,kBACA,OAEA,yBACA,aACA,SACA,CAkBA,MAKwD,OClVxD,UEuBA,QASA,eASA,aAQA,iBACA,IAWA,YACA,IAEA,YACA,aAGA,SACA,wDAGA,kFACA,QAYA,kBACA,IAEA,YACA,aAGA,SACA,8DAGA,kFACA,QAWA,iBACA,OACA,EAUA,gBACA,aACA,6BAIA,WADA,IASA,kBACA,cAEA,kDACA,IAQA,sBACA,cAEA,kDACA,IASA,WACA,OAEA,YACA,YAGA,OACA,QASA,eAEA,mBACA,KAIA,yBACA,IAOA,QACA,oBACA,OAkBA,UACA,MACA,gBAEA,OACA,oBACA,iBAGA,OACA,QAWA,gBAA0B,gBAAyC,gBACnE,MACA,wCAGA,iCACA,kBAGA,OACA,QAYA,qBAAsC,KACtC,cACA,oBAEA,sBAEA,mBACA,MAGA,yBACA,EAKA,SACA,iCACA,MAQA,gBACA,oBACA,MAQA,gBACA,oBACA,MAUA,gBACA,oBACA,SAOA,mBACA,oBACA,MAQA,kBACA,aACA,QAOA,mBACA,aACA,IAQA,mBACA,oBACA,SAKA,kBACA,aACA,OAOA,SACA,MAEA,MAKA,mBAJA,6BAGA,UsNvWA,EACA,mBAOA,iBACA,CAOA,sBACA,EAKA,iBACA,kBACA,MAKA,MACA,OACA,SAKA,QACA,8BACA,gBAOA,SACA,eAEA,SAGA,mBADA,MASA,mBACA,wBACA,WC3CA,EACA,QAWA,mBAOA,SAEA,oBAMA,wBAGA,4FAMA,wBASA,+FAQA,UACA,cASA,kBACA,yCACA,gDASA,iBACA,kBACA,MASA,gBACA,gCACA,qCAaA,gBACA,wCACA,UAQA,aACA,sBACA,MAQA,WACA,sBACA,IASA,eACA,sBACA,QAUA,MACA,OACA,cAQA,UACA,uBAEA,UAKA,MAJA,kCAGA,eAYA,gBAA0B,gBAAyC,gBACnE,MACA,wCAGA,iCACA,kBAGA,OACA,QAQA,gBACA,sBACA,eAQA,gBACA,sBACA,eAUA,gBACA,sBACA,eAOA,mBACA,sBACA,kBCtPA,EACA,QAMA,eAOA,MAGA,8BAEA,IAOA,oBACA,2BACA,WAQA,aACA,oBACA,MAQA,gBACA,iDACA,EAQA,WACA,wBACA,IAQA,gBACA,qBAEA,uBACA,MASA,sBACA,cAEA,yFACA,EAWA,iBACA,mBACA,mBAGA,uBAEA,aAMA,gBAGA,iGACA,qBAWA,iBACA,OAEA,6BACA,gBACA,uBAGA,qBACA,UAEA,IAMA,kBAGA,mGACA,MAQA,iBAEA,UACA,aAMA,8BAIA,wHACA,KASA,mBACA,oBACA,WAQA,SACA,+BACA,SACA,EtNvLA,mBASA,mBACA,CAOA,cAQA,sBAGA,8BAEA,IAQA,iBACA,uBACA,MAQA,gBACA,uBACA,SAQA,cACA,OACA,oBAqBA,aAEA,gCAIA,2BAFA,IAUA,YACA,uBACA,UAOA,cACA,8BACA,WAQA,iBACA,uBACA,eAUA,uBACA,uBACA,qBASA,YACA,4DAEA,kCACA,kBAmBA,iBACA,uBACA,gBAOA,kBACA,0BACA,aASA,oBACA,GAEA,cAEA,QACA,mBAGA,kBAGA,oBACA,gBAUA,sBACA,wBAEA,0BACA,iBAGA,KACA,QAaA,iBACA,OAEA,cACA,uBAGA,kBACA,QAOA,SACA,eAEA,wBAEA,6BACA,GAEA,gCACA,4BAEA,SAEA,CACA,QASA,mBACA,OAEA,mBACA,CAEA,sBACA,WAEA,eAGA,uBAGA,YAEA,wBACA,aAMY,EChSZ,QAmBA,aAA0B,KAC1B,sBAMA,2BAGA,yHAEA,2BACA,mBACA,QACA,wFAAK,CAUL,mBAaA,0CAWA,qBACA,sCAEA,sFAUA,oCASA,kCAWA,kCAQA,wFAQA,wEASA,uCACA,MAKA,oBACA,OACA,KAcA,QACA,WAEA,EACA,UACA,gBAEA,gBAAM,QAAc,cACjB,kBAGH,eACA,gBAEA,iBAQA,OACA,OACA,+BAEA,aAEA,WAUA,QACA,cACA,sCACA,iBAGA,gDACA,gBAAW,CAIX,uEACA,aAAW,CAGX,yCAEA,aACA,4BAEA,UAMA,sBALA,QAEA,uBAKA,kCACG,sBACH,IAEA,WACA,mBACI,MACJ,SAEA,0DACA,iCAGA,cACA,MAEA,oBACA,cAEA,uBACA,eAEA,aACA,eAEA,eACA,QACA,cACA,iCAEA,YACA,sBAEA,UAGA,mBAUA,YACA,cACA,sCACA,iBAGA,mCACA,mBAAW,CAIX,0EACA,aAAW,CAIX,yCAEA,cACA,yBAEA,cACA,cAYA,kCAEG,mBAbH,gBACA,gBAEA,sBACA,sBAEA,cAGA,wCAKA,IAEA,WACA,mBACI,MACJ,SAEA,gEACA,mCAGA,YACA,QAEA,oBACA,uBAEA,gBACA,eAEA,aACA,eAEA,eACA,WACA,iCAEA,8BAEA,EACA,KEjUA,IDVA,WACA,kBACA,eACA,SAEA,EEkBA,QAOA,iBACA,4BAQA,iCAGA,iFAOA,kHAAsH,CAItH,uBACA,cASA,UA+BA,YACA,MAQA,aACA,gBACA,KAKA,cACA,4BACA,IAcA,aACA,YAEA,eAAkB,qBAA0B,EAC5C,sCAGA,UACA,QAUA,YACA,uCACA,OASA,eACA,mCAEA,2DACA,IAQA,gBACA,8DACA,IAQA,iBACA,gEACA,IAQA,gBACA,OACA,gBAQA,cACA,iCACA,SAQA,eACA,iBACA,WAGA,kCAGA,YACA,WAEA,OACA,aAEA,SACA,gBAGA,uBACA,QAEA,SAGA,OAuBA,2BAA4C,KAC5C,iBAEA,aACA,mBAEA,UACA,QAUA,gBACA,2BACA,EAOA,eACA,uBACA,0BAEA,iCAAqC,CAErC,gBASA,iBACA,iBACA,KAIA,+BAEA,sDAEA,iCACA,IASA,qBACA,cACA,mBAEA,qBAEA,mBACA,MAGA,yBACA,EASA,gBACA,+BAEA,UACA,SAGA,oBADA,KAWA,WACA,OACA,4BAiCA,YACA,OACA,6BAQA,WACA,OACA,2BAYA,cACA,OACA,OACA,kBAEA,eACA,cACA,OAEA,aACA,iCACA,WACA,sBAEA,UACA,aACA,8CACA,MAEA,MACA,QAIA,sBAEA,oCACA,MACA,WAGA,wCACA,iBACA,UAGA,gCACA,OACA,SACA,QAAI,KACJ,IACA,aAGA,gCACA,EACA,CACA,CAWA,+BACA,+BAGA,sBACA,KAGA,YAEA,2EAEA,oBAEA,aAGA,QAEA,SACG,8DAEH,uBAEA,4BAEA,oBAGA,cAGA,QAEA,UACA,CAEA,CACA,QAaA,kCACA,+BAGA,sBACA,KAGA,YAEA,wFAGA,eAEG,uEAEH,uBAEA,iBAGA,YAEA,WAEA,CACA,QAgBA,iCAEA,YAGA,+BAaA,WAXA,gDAGA,gBAIA,oBAGA,mCA8BA,kBACA,uBAGA,OAKA,sBAOA,wCAHA,8CAEA,KAsBA,qBACA,IACA,4BACG,0BACH,MAEA,QACA,aACI,kBACJ,wBACI,mBACJ,uBAEA,qBAGA,eACA,8BACA,CAQA,sBACA,OAOA,wFAAkG,CAGlG,0DACA,UAQA,uBACA,OAOA,0FAAoG,CAGpG,0DACA,YASA,sCACA,4BAMA,iCAGA,yGAEA,mBAEA,mBACA,OAQA,6BACA,+BACA,QAQA,qBACA,IACA,kDAGA,sBAOA,WACA,QACA,iHAAK,YAIL,yCACA,KmN7vBA,EACA,QASA,sBAOA,eAQA,6DACA,qBAcA,qBACA,cAA0B,iBAC1B,qBAQA,kBACA,gCACA,IAQA,aACA,qCACA,MAOA,WACA,mBACA,IASA,oBACA,+CACA,IAWA,sBACA,GACA,cAGA,sEACA,6DAEA,WACA,KAOA,gBACA,YAEA,4DACA,UAQA,WACA,wDACA,IAQA,kBACA,uDACA,MAwBA,iBACA,MAEA,MAoBA,YAjBA,2CAGA,mCAGA,gCAGA,+BAIA,iCAGA,QAmBA,mBACA,2BAGA,YACA,aAEA,mCAGA,aAGA,+BAGA,WAGA,KACA,WAGA,OACA,KAyCA,uBACA,MACA,2CAEA,oCACA,mBAGA,0BACA,uBAEA,OACA,wBAGA,yCACA,KACA,aACA,MAGA,2CACA,qCACA,SAEA,OACA,wBAGA,oBACA,qBACA,EAEA,CACA,QAWA,WAAwB,KACxB,qBAEA,KACA,SAiBA,WAAyB,KACzB,cACA,OAEA,4BAEA,mBACA,gBAEA,IAeA,eAA6B,KAC7B,cAEA,aAEA,kBAEA,kBACA,gBAEA,YAYA,yBACA,6BAGA,YAEA,6DACA,sBACA,gBAAoB,MAAmB,WACvC,cACA,kCACA,OACA,yBACA,4BACA,YAGA,6BAEA,kBACA,CAIA,CACA,QAYA,0BACA,6BAEA,gBACA,kBAAmB,MAAmB,WACtC,cAEA,sCACA,kBACA,CAOA,WAAkB,MAAmB,WACrC,SAEA,iBAAuB,MAAmB,WAC1C,SAEA,gDACA,wBAEA,EACA,CAEA,CACA,QAQA,oBACA,0CACA,IAaA,2CACA,IACA,wBACG,0CACH,YAGA,gCACA,GACA,iBACA,gEACA,MAWA,mCAEA,uBACA,iBAIA,qDAKA,qBAWA,kBACA,yDACA,iCACA,eACA,WACA,oBAEA,iBAEA,2CAEA,0CACA,YAMA,CACA,qDACA,+BACA,mBACA,YACA,oBAOA,8CAEA,iBAGA,uCACA,YAEA,aACA,4BACA,CAqCA,0CACA,YAKA,0BACA,aACA,SACA,SACA,gFAGG,mBACH,4BAEA,YAGA,sCACA,+BAHA,gBAKA,kCACA,GACA,CAYA,6BACA,qBACA,oBAEA,0CACA,UAEA,IAEA,sBAEA,wBACA,uBAEA,kBAEA,mBAEA,cACA,kBACA,wCAEG,gCAEH,gBACA,YACA,eAIA,2CAGA,+BAaA,4CAPA,uBACA,8BACA,8BAIA,YAWA,uCACA,MACA,SAEA,4CACA,UAWA,4CACA,WACA,SACA,kCAEA,+BAQA,0BACA,2BACA,IASA,mBACA,iDACA,UAQA,mBACA,6DACA,WAUA,8BACA,YACA,mBAEA,4BACA,YAiBA,2BACA,IAOA,0BACG,sFACH,0CAMA,cAGA,UACA,mCAIA,aAKA,gCAIA,iBAA6B,EAAQ,yBAErC,OADA,uCAUA,mBAA6B,MAAmB,6BAEhD,KADA,qCAQA,KACA,QASA,qBACA,sDACA,OCp0BA,ECGA,GCNA,IDOA,aACA,aACA,OACA,gBACA,MAGA,gBACA,CAEA,WCdA,gBAUA,OrNSA,kBmNlBA,UACA,MACA,WAEA,EnNeA,sBqNTA,WACA,YACA,WAEA,WACA,IAEA,wBACA,EAMA,MALA,QAEA,kBAEA,KCpBA,EtNiBA,gBsNhBA,WACA,YACA,WAEA,+BACA,ECNA,EvNkBA,gBuNjBA,WACA,QACA,qBCFA,ExNkBA,YAEA,IwNnBA,aACA,YACA,WAEA,cACA,YAEA,YAEA,KACA,IAEA,KChBA,4BCCA,SCAA,GDCA,WACA,YACA,IACA,WACA,OAAK,UACL,IACA,UACA,EAAK,UACL,CACA,OACA,EAEA,KCVA,yBAGA,wCAGA,gCAGA,eAGA,yBACA,2BACA,kFAoBA,KCrCA,GDsCA,WACA,KACA,MAEA,sBACA,0BACA,MAEA,EEpDA,GDOA,aACA,OACA,WACA,eAEA,eCVA,UCGA,gBCCA,gBAUA,yBCbA,gBAUA,e/NSA,kB6NhBA,UACA,qBACA,QGFA,EhOiBA,sBgOhBA,WACA,iCACA,WAEA,EhOaA,gB8NPA,WACA,YACA,eACA,OACA,WACA,KAnBA,oCAoBA,qBACA,WCxBA,E/NyBA,gB+NXA,WACA,YACA,oCACA,SEjBA,EjO0BA,YAEA,IiOhBA,aACA,YACA,yBACA,WAJA,8BAKA,IAEA,KCjBA,iBAEA,OCIA,MCDA,GCFA,WACA,OACA,sDACA,aACA,gBACA,QAEA,ECJA,GFAA,aACA,SACA,eACA,qCACA,UACA,GAEA,EnOQA,kBkOdA,UACA,eACA,MACA,eACA,eAEA,OEXA,EpOoBA,sBqOfA,WACA,mBACA,YCHA,EtOiBA,gBsOhBA,WACA,mBACA,MCHA,EvOkBA,gBuOjBA,WACA,mBACA,MCFA,ExOkBA,YAEA,IwOnBA,aACA,mBACA,SACA,IAEA,KCbA,MxOeA,kBsNVA,UACA,eACA,MmBHA,EzOYA,sByOXA,WACA,sBACA,YCHA,E1OaA,gB0OZA,WACA,sBACA,MCHA,E3OcA,gB2ObA,WACA,sBACA,MAEA,E3OUA,YAEA,IwOTA,aACA,YACA,4CACA,QAJA,+BAMA,aACA,SACA,IAEA,KIjBA,MCLA,GDMA,aACA,YACA,MAEA,OACA,gBAIA,aACA,QAEA,YCfA,gBASA,eCdA,GDeA,aAIA,WACA,uCACA,YAEA,YCdA,KCwBA,GDvBA,WACA,WACA,UAEA,EEJA,GDwBA,WACA,OACA,cACA,aAEA,aACA,QAEA,UAEA,cACA,QACA,WALA,kBAMA,aACA,oBAGA,QACA,QAEA,EEhDA,GDKA,aACA,gBACA,QAEA,EETA,GDCA,aACA,CACA,cAEA,kCACA,QAEA,SADA,SAGA,EhPhBA,GiPOA,aACA,QACA,MAEA,iBACA,UACA,YAEA,KACA,QAEA,YjPVA,uCAUA,CACA,QAGA,MkPbA,MCHA,GDIA,aACA,aACA,QAEA,EEFA,GDLA,aACA,YACA,MACA,WAEA,OACA,cAEA,KACA,QAEA,EETA,GDIA,eACA,OACA,yBACA,KAEA,EEfA,GDOA,WACA,OACA,YAEA,aCTA,YCFA,iBAEA,WCFA,iBAEA,OCFA,iBAEA,WxPEA,SACA,kBAEA,sBACA,kBAEA,sBAGA,8BAOA,gBAGA,YACA,UACA,UACA,UACA,UAQA,qCAQA,gBACA,sBACA,sBACA,mBACA,4BACA,UACA,aA3CA,oBA4CA,uBAEA,aACA,KACA,kBACA,kBACA,kBACA,kBACA,kBAGA,WACA,QAGA,MyPpEA,gBAGA,gBAQA,eCTA,GDUA,WACA,SACA,WAGA,eAKA,2CAJA,qBACA,gBAEA,QAGA,UCpBA,WCGA,MCCA,GDAA,WACA,2BACA,YAEA,qBADA,YAGA,EERA,GDGA,aACA,wBACA,iDACA,WAEA,EEJA,GDHA,aAEA,CAEA,oBADA,KAGA,EERA,GDMA,iBACA,QACA,MAEA,WACA,WAEA,MACA,aAEA,UACA,QAEA,EEbA,GDLA,WACA,QACA,YAEA,MAIA,8BAHA,QACA,KACA,IAGA,EEhBA,GDYA,eACA,qBACA,2BACA,YAEA,KCTA,OCFA,GDGA,WACA,qCACA,SAEA,qBADA,WAGA,EEVA,GDEA,aACA,CAEA,SADA,QAGA,EEDA,GDLA,WACA,QACA,YAEA,MAIA,4BAHA,GACA,MACA,IAGA,EEdA,GDUA,eACA,qBACA,2BACA,YAEA,UCbA,OCFA,eACA,0BAQA,eCHA,GDIA,WACA,qBACA,WAEA,EERA,GDCA,aACA,wBACA,iDACA,OAEA,EEZA,GDwCA,iBACA,SAGA,uBA5BA,uBAgCA,UAzCA,wBACA,sBA2CA,QAlCA,oBAuCA,YAtCA,6BACA,6BACA,0BACA,2BACA,2BACA,2BACA,kCACA,4BAcA,uBAoBA,YAlDA,eAsDA,cArDA,uBAGA,kBAqDA,aAvDA,kBA0DA,UAzDA,eA4DA,cAzDA,kBA2DA,YAEA,YCnEA,OCFA,GDGA,WACA,cACA,QAEA,KCNA,WACA,yCACA,YAEA,MAEA,OzQEA,MACA,wBAKA,uBACA,gCAGA,wBAoBA,UA5BA,kBA6BA,GAdA,2BACA,qBAcA,GA7BA,uBACA,iBA6BA,GAdA,4BACA,yBAcA,GAbA,yBACA,uBAaA,GAZA,0BAfA,gBA4BA,GA3BA,0BA4BA,GA1BA,sBACA,gBA0BA,GAzBA,sBACA,mBAyBA,GAfA,0BACA,8BAeA,GAdA,2BAGA,2BAYA,GApCA,yBAoDA,GAzCA,0B0QRA,MCTA,GDUA,WACA,OACA,YAEA,ECbA,QAMA,cAOA,aACA,IAWA,YACA,IAEA,YACA,aAIA,UAMA,oDAGA,iFACA,QAQA,kBACA,cAEA,kDACA,IAQA,sBACA,cAEA,kDACA,IAQA,WACA,OAEA,YACA,YAGA,OACA,QASA,eAEA,aACA,iCAEA,SAEA,IAWA,gBAA0B,gBAAyC,gBACnE,MACA,wCAGA,iCACA,kBAGA,OACA,QAYA,qBAAsC,KACtC,cACA,oBAEA,sBAEA,mBACA,MAGA,yBACA,EAKA,SACA,iCACA,MAOA,iBACA,WAEA,oBACA,oBAEA,gBAOA,SACA,YAGA,MAGA,gBADA,QAmEA,ECvPA,SACA,mBAMA,eACA,CAUA,aACA,OAOA,QACA,oBACA,KAKA,MACA,OACA,SAOA,WACA,aACA,KAEA,YACA,yBAEA,WACA,OASA,aACA,UAIA,2CACA,KACA,E3QpEA,QAOA,kBACA,MAEA,sBACA,KAiFA,UACA,QAEA,yCACA,aAAY,CAIZ,+DACA,sBAGA,uBAEA,OA+BA,YACA,UACA,sCACA,SAEA,OACA,WACA,CACA,UACA,UAGA,QAGA,OACA,KAYA,eACA,MAEA,eACA,sCACA,SAGA,iBACA,CACA,UACA,UAGA,SAGA,qBACA,IAQA,iBACA,IACA,gCAGA,6BACA,OAEA,6DACA,IAQyB,EChMzB,mBAeA,mBACA,IAQA,aAQA,mBACA,MAEA,QASA,aAGA,oCASA,sBAEA,8BAEA,yBACA,gBACA,+BACA,QAQA,iBAEA,qBAEA,0CACA,6BAUA,oCACA,IAQA,iBACA,uBACA,MAQA,cACA,OACA,0BAWA,aAEA,gCAIA,2BAFA,IAWA,YACA,MAEA,MACA,yBACA,uBAKA,sDAIA,UAYA,+BAXA,iCAGA,0CAKA,0CAEA,iBAWA,kBACA,iCACA,aAQA,YACA,aACA,YAQA,iBACA,uBACA,UAOA,cACA,8BACA,WAOA,oBACA,CACA,4BAGA,SACA,2BAKA,oCACA,OAEA,OAUA,iBACA,mBAEA,UACA,uDAGA,WACA,sDAEA,UAQA,gBACA,IACA,iBACA,8CAMA,0BACA,wBACA,OAEA,yBACA,WAAuB,IAAc,KAGrC,IACA,QAEA,CACA,MAEA,oBACA,MAQA,gBACA,OACA,WAGA,qBACA,WAGA,gCACA,MASA,kBACA,+BAEA,MACA,kBACG,YACH,kBAEA,uBAEA,QAWA,oBACA,6BACA,YAEA,IAEA,cAEA,QACA,mBAGA,kBAEA,6BACA,KACA,IAGA,IACA,QASA,mBACA,sCAGA,MACA,cACA,sCASA,YACA,cACA,oCASA,wBACA,SAUA,sBACA,6BAEA,aAAsB,OAAqB,IAC3C,6BAGA,2BACA,WAUA,aACA,MACA,iBAIA,YACA,SAIA,yBACA,KAIA,8EACA,oCACA,KAIA,+BACA,qCACA,WAKA,6BACA,wBACA,OAKA,+BACA,wCACA,WAIA,SACA,QAWA,eACA,+BACA,mCACA,OAWA,kBACA,+BACA,mCACA,UAWA,eACA,UACA,0BACA,OAIA,SACA,QAOA,gBACA,sBACA,MAeA,cACA,kCAEA,YACA,gBAEA,iBACA,2BAEA,KACA,mBAEA,QASA,YACA,qBACA,MAOA,gBACA,qBACA,MAWA,eACA,UACA,yBACA,OAIA,SACA,QAWA,kBACA,+BACA,kCACA,UAWA,mBACA,gBACA,qBAEA,UACA,MACA,SAGA,aACA,MAEA,OACA,KASA,uBACA,wBACA,QAQA,qBACA,+BACA,MAQA,wBACA,+BACA,SAQA,uBACA,8BACA,SAyBA,cACA,+CACA,yCAAyD,OAAY,QAAS,gBAC9E,wCAA4D,OAAa,SAAS,iBAElF,iBACA,eAAqC,YACrC,eAAoC,YACpC,eAAiC,KACjC,GAckB,ECvrBlB,QAWA,mBAOA,SAEA,yBAMA,oBAGA,gGAMA,oBASA,8FAQA,UACA,cAaA,gBACA,8CACA,MAQA,aACA,sBACA,MAQA,WACA,sBACA,IASA,eACA,sBACA,QAUA,MACA,OACA,cAWA,gBAA0B,gBAAyC,gBACnE,MACA,iDAEA,OACA,iCACA,kBAGA,OACA,Q0QlJA,EACA,QAmBA,aAA0B,KAC1B,sBAMA,2BAGA,2IACA,6BACA,QACA,uFAAK,aAeL,0CASA,qBACA,sCAEA,gFASA,sCASA,oCASA,kCAUA,kCAQA,wFAQA,wEACA,IAKA,oBACA,OACA,KAcA,QACA,SAEA,EACA,UAEA,UAAM,QAAc,cACjB,kBAGH,eAEA,WAQA,OACA,OACA,+BAEA,aAEA,WAUA,QACA,kCACA,uBACA,aAGA,wCACA,iBAAW,CAIX,uEACA,aAAW,CAIX,YAGA,sBACA,MAEA,gCAEA,oBAGA,mBACA,OACA,qBAGA,WACA,4BACA,UAKA,oBAHA,QAKA,wDACG,QACH,wCAwBA,IAEA,WACA,mBACI,MAEJ,uEAEA,aACA,MAEA,oBAEA,mBACA,eAEA,mCACA,eAEA,aACA,oBAEA,gBACA,sBAEA,gCAGA,4BAnDA,mCACA,QAEA,gBACI,YACJ,cACA,OAGA,mBACA,0CACA,kBACA,UAGA,kBAGA,cAEA,mCACA,eACG,CAuCH,YACA,kCACA,uBACA,aAGA,2BACA,mBAAW,CAIX,0EACA,aAAW,CAIX,YAGA,sBACA,MAEA,kCAEA,qBAGA,8BACA,EACA,4BAGA,MACA,4BACA,WAUA,cAEA,wDAEG,kBAbH,iBAEA,gBACA,sBAEA,oCAGA,0BAMA,wCA0BA,IAEA,6BAEA,oEAEA,MACA,QACA,QAGA,IAEA,6BAEA,sBAEA,mCACA,eAEA,aACA,qBAEA,wDAEA,WAlDA,0CACA,aAEA,gBACI,gBACJ,cACA,OAGA,oCACA,+BAEA,2BACA,mBACA,YACA,eAEA,QAGA,qBAEA,mCACA,eACG,CAuCH,8BAKA,OAEA,iEACA,sFACA,6BASA,8BAPA,eAEA,aAMA,qGACA,8BASA,+BAPA,eAEA,cAMA,CACA,cACA,CACA,OACA,OACA,mBACA,eAGA,UAyCA,EzQxbA,mBAMA,mBACA,CAQA,kBACA,iBAKA,aAEA,qDAIA,qCAFA,KAOyB,EChEzB,gBAUA,YACA,mBAIA,mBACA,CAQA,sBAYA,0BAUA,eAEA,eACA,aACA,qBAEA,gBACA,SAMA,mCAGA,iFAEA,gDAEA,6BAEA,KACA,iDAKA,mCACA,0DACA,IAAG,EAAG,UACN,QACA,EyQ3EA,SACA,QAOA,iBAOA,MAOA,cACA,QASA,gBACA,uBACA,QAGA,wCACA,IASA,iBACA,uBACA,QAGA,0CACA,IAQA,gBACA,OACA,gBAQA,cACA,oEAEA,uBACA,UAQA,WACA,oBACA,IAQA,sBACA,YAEA,cACA,uBACA,WAEA,kBAIA,MACA,QAQA,gBACA,+BAEA,UACA,SAGA,oBADA,KAmBA,2BAA4C,KAC5C,iBAEA,aACA,mBAEA,UACA,QAOA,eACA,uBACA,0BAEA,iCAAqC,CAErC,gBASA,qBACA,cACA,mBAEA,qBAEA,mBACA,MAGA,yBACA,EAQA,WACA,8CACA,MAYA,YACA,OACA,6BAYA,WACA,OACA,4BASA,eACA,SACA,iBAIA,0BACA,8CAIA,qBACA,mBAGA,iBAEA,UAEA,GACA,cAEA,SAEA,gBACA,oBACA,EAEA,UACA,uBACA,EAEA,MACA,YAIA,WACA,WACA,SAGA,sBACA,uBAEA,2BACA,OAAG,iBACH,mBAEA,2BACA,OAEA,mBAGA,0BACA,OAoBA,qBACA,IACA,4BACG,0BACH,MAEA,QACA,wCACI,mBACJ,wBACI,mBACJ,uBAEA,qBAGA,SACA,YACA,CAQA,sBAEA,SACA,4DAGA,cAOA,sFAAgG,CAGhG,wCACA,EAQA,uBAEA,SACA,wCAGA,oBAOA,wFAAkG,CAGlG,kCACA,MAQA,6BACA,4BACA,OAQA,ExQrYA,QASA,sBAMA,eAOA,6DACA,qBAaA,qBACA,cAA0B,iBAC1B,qBAOA,kBACA,gCACA,IAQA,aACA,qCACA,MAOA,WACA,mBACA,IAkBA,cACA,4CAAoE,WACpE,wBAGA,yDACA,gCAGA,gCACA,6BAGA,SACA,WAkBA,aACA,kBAEA,kEACA,WAGA,sDAAgE,WAChE,uBACA,cAGA,0BACA,qBAGA,YACA,4BAGA,SACA,WAQA,WACA,iEACA,IASA,oBACA,+CACA,IAYA,sBACA,GACA,cAGA,sEACA,6DAEA,WACA,KA8BA,iBACA,MAEA,MAoBA,YAjBA,2CAGA,mCAGA,gCAGA,+BAIA,iCAGA,QAwBA,mBACA,2BAGA,YACA,aAEA,mCAGA,aAGA,+BAGA,WAGA,KACA,WAGA,OACA,KAWA,WAAwB,KACxB,qBAEA,KACA,SAQA,oBACA,0CACA,IAgBA,WAAyB,KACzB,cACA,OAEA,4BAEA,mBACA,gBAEA,IAeA,eAA6B,KAC7B,cAEA,aAEA,kBAEA,kBACA,gBAEA,YAQA,kBACA,uDACA,MAWA,4CACA,WACA,MACA,YAEA,YAQA,0BACA,2BACA,IAUA,uCACA,MACA,SAEA,4CACA,UASA,mBACA,iDACA,WAQA,mBACA,2DACA,EAUA,8BACA,YACA,mBAEA,4BACA,YAGA,ECzaA,QAIA,cAOA,6BAQA,qCASA,6CAGA,0CACA,OAIA,mEAEA,8DACA,QAAG,EAAG,UAGN,6CACA,MACA,cAGA,4BACA,kCAEA,YACA,QACA,kCAGA,wEAEA,6BACA,8BAAG,EAAG,UACN,OAWA,kBACA,0BACA,kCACA,QAOA,qBACA,cAEA,uBACA,oBAOA,sBACA,cAEA,sBACA,oBAKA,gBACA,6BACA,qCACA,QAUA,kBACA,iCACA,MAQA,iBACA,iCACA,MAQA,gBACA,oEACA,KAQA,eACA,kEACA,KASA,mBACA,SACA,CACA,sBAGA,uBAEA,2BACA,aASA,kBACA,SACA,CACA,uBAGA,uBAEA,2BACA,YA+BA,+BACA,kCACA,QAoBA,sBACA,SAEA,wCACA,gBAEA,4BACA,IAKA,SACA,QAIA,eAEA,YAAkB,EAAgB,IAClC,6BAGA,aACA,QASA,qBACA,0BACA,mCACA,SAwBA,kBACA,iDACA,gDAEA,YACA,KAAG,6BACH,aACG,WACH,sBACG,eACH,mBACG,OACH,OAEA,mBACA,sBAGA,kBACA,QACA,CA2BA,qBAEA,OAIA,IACA,IAGA,EANA,UAOA,cAMA,kBACA,SACA,mBACA,kBACA,KAIA,UACA,uCAMA,uCAEA,KAcA,+BAGA,WACA,eAEA,aACA,uCACG,cACH,0BAKA,IAuFA,EwQrbA,SACA,QAIA,cAOA,qBAaA,gCACA,IAgBA,SACA,CACA,yBAGA,4CACA,kCAGA,8BACA,SAiBA,aACA,OACA,0BAGA,kCACA,oCAMA,aAkBA,UACA,CACA,yBAGA,oDAEA,UACA,iBAGA,gBAEA,aACA,YAIA,MAkBA,YACA,CACA,yBAGA,wCAEA,gBACA,gCAGG,cAIH,QACA,IAYA,0BACA,OAEA,2CAEA,kBACA,iBAGA,yBAEA,QAGA,CAIA,qEADA,UAcA,8BACA,gBACA,yBAEA,EAiBA,iCAdA,gBACA,6BAGA,cAGA,gBACA,OAGA,YAEA,UAEA,EvQzRA,QAOA,eAQA,iBAQA,oBAGA,8BAEA,IAOA,oBACA,aACA,aAQA,iBACA,uBACA,MAQA,gBACA,uBACA,SAQA,cACA,OACA,oBAQA,WACA,OACA,KAQA,aACA,OACA,KAUA,MACA,OACA,qBAQA,YACA,uBACA,UAOA,cACA,8BACA,WAQA,iBACA,uBACA,eAUA,uBACA,uBACA,qBAOA,UACA,CACA,QAaA,iBACA,OAEA,cACA,uBAGA,kBACA,QAqBA,iBACA,uBACA,gBAOA,kBACA,0BACA,aASA,oBACA,GAEA,cAEA,QACA,mBAGA,kBAGA,oBACA,gBAUA,sBACA,wBAEA,0BACA,iBAGA,KACA,QAQA,SACA,MAEA,0BACA,mBAGA,UACA,QASA,mBACA,MAEA,eACA,UAEA,eAGA,uBAIA,mBACA,UAMY,ECzMZ,QAOA,eAA+C,KAO/C,MAOA,uCAAgC,YAChC,QAkBA,mBAGA,wBAIA,kDAIA,2DAKA,qDACA,sCACG,OACH,8CACG,OACH,kDACG,gDACH,wEACG,UACH,4CAEA,SAeA,oBAEA,cAGA,4CACA,WACA,0DACA,UACA,CACA,OAGA,2BAKA,+BACA,qBACA,mCACA,2BAEA,kCAAuC,iBAEvC,OAEA,4CACA,WACA,eAGA,qDACA,0CAEA,OACA,CAYA,iBAEA,wBACA,MAEA,yBACA,6DAEA,aACA,kBACA,WACA,wBAEA,mBAYA,mBACA,0CAEA,oCAAuC,CAAgB,aACvD,mBAMA,SALA,CACA,iBAGA,UAEA,CAgBA,4BACA,IAMA,iDAGA,wBACA,WACA,0DACA,0BAQyB,IAAU,KACnC,GARA,CACA,OACA,QACA,eACA,oBAGA,uBAEA,EAYA,mBACA,MAMA,mBACA,YAGA,iCAEA,yCAIA,0BACA,SAEA,2DACA,sCACA,aAWA,oBACA,uEACA,4BAEA,sDAA2B,CAAY,oBAEvC,gCACA,WAEA,2DACA,QAGA,iBACA,CACA,yBACA,KAGA,6CACA,oDAEA,cAEA,qCACA,SACA,CACA,YACA,cAIA,kDACA,qDAEA,cACA,CAcA,qBAEA,qBAKA,yCAGA,uBACA,SACA,OAQA,SANA,0BACA,CACA,aACI,sBAEJ,cAIA,cAGA,gDACA,WAGA,WACA,UAGA,iBACA,CACA,gEACA,QACA,aAGA,oCACA,cACA,EAUA,2BACA,SAEA,wBACA,WAEA,aAEA,2BACA,2BAEA,kBAEA,CACA,QAWA,+BACA,SAEA,wBACA,aAGA,SACA,QAUA,gCACA,SAEA,eAEA,sBACA,qCAGA,uBACA,2BAGA,yBACA,QAeA,oBACA,aAKA,8BAEA,mCACA,eAgLA,EAUa,SC5sBb,SAWA,GACA,mBAMA,mBACA,CASA,kBAQA,iBACA,iBAKA,aAEA,qDAIA,qCAFA,KAWA,SACA,eAGA,SAGA,uBADA,UAWA,aACA,6CACA,QAOA,EACA,GAIyB,oBCpFzB,mBAUA,mBACA,CAQA,kBACA,iBAKA,aAEA,iDAIA,iCAFA,KASA,oBACA,yBAMA,qCAEA,iFAKa,ECzDb,6BAOA,iBAOA,KAWA,WACA,QACA,wBCbA,CDGA,SAOA,OCTA,SAmFA,UACA,SACA,WACA,WACA,cACA,aACA,aACA,SACA,SACA,SACA,OACA,OAIA,OAGA,YACA,cACA,YAIA,mBAAqB,GAAY,UACjC,gBAEA,oBACA,gBAGA,WAAqB,GAAY,MACjC,QAIA,gBAAsB,IAAa,OACnC,aAGA,QACA,SAlHA,GClBA,mBAUA,mBACA,CAQA,kBACA,kBAKA,aAEA,8CAIA,8BAFA,KASA,oBACA,yBAMA,qCAEA,2EASA,UACA,8BAEA,0BACA,yCAGA,iBACA,QAWA,EC5EA,QAOA,eAOA,MAGA,oCAEA,IAKA,oBACA,8BACA,WAQA,iBACA,uBACA,MAQA,cACA,OACA,oBAQA,WACA,OACA,KAQA,aACA,OACA,KAUA,MACA,OACA,qBASA,kBACA,iCACA,aAQA,YACA,aACA,YAQA,iBACA,uBACA,UAOA,cACA,8BACA,WAUA,oBACA,6BACA,YAEA,IAEA,eAEA,QACA,mBAGA,kBAEA,6BACA,KACA,IAGA,IACA,QASA,sBACA,6BAEA,aAAsB,OAAqB,IAC3C,6BAGA,2BACA,WAUA,iBACA,WACA,cACA,EAOY,YCxHZ,IAvDA,CACA,gBAuDA,WACA,OACA,iBAEA,MAEA,KA0BA,EAtFA,eAuFA,WACA,WAEA,gBAMA,iCAGA,+GAMA,oBAGA,8DACA,oBACE,8BACF,WAEA,gBAEA,iDACA,mBAEA,GACA,OAEA,WACA,cA4BA,EArJA,mBACA,gBAqNA,WACA,WACA,eAEA,sDAMA,yBAIA,oJACA,wDAEA,OAIA,uCAHA,cAEA,cAsBA,EA9PA,UACA,UACA,MAoVA,aACA,CAIA,0BACA,WACA,WAIA,uCACA,WACA,QAGA,yBAEA,kBAEG,wFAEH,+BACA,wBAKA,uBAEA,YAKA,qBACA,eAGA,wBACA,mBAIA,OAEA,MACA,CAcA,EAhZA,QACA,QACA,aA+eA,aACA,MACA,8BAIA,uDACA,qBAIA,mCACA,YAIA,eACA,iCAIA,iCAGA,0CAGA,IAGA,kCACA,SAGA,mBACA,eAEA,kCACA,gBAIA,QACA,KAWA,EApiBA,OAqiBA,aACA,MAMA,8BAGA,2CAGA,QACA,YAMA,mDACA,iBAGA,+CACA,QAEA,QAGA,MAAQ,SAAmC,OAC3C,aAGA,yBAGA,iBAGA,mBACA,cAEA,sBAEA,WACA,YAaA,EA/lBA,OAgmBA,aACA,oBAEA,iBAKA,aAJA,uCACA,mBAEA,cAeA,GA4gBA,SAKqB,iBC7jBrB,mBACA,aACA,cACA,2FAIA,wB+PtlBA,EACA,QAIA,cAUA,sBACA,IA4BA,SACA,IAGA,6BACA,2CAMA,iCACA,2BAMA,UALA,yBAEA,YAIA,OA+BA,UACA,2BAEA,aACA,YAIA,wBAKA,wBACA,OA8BA,aACA,cACA,+BAEA,sCAGA,mCAOA,cA8BA,YACA,2BAEA,OACA,gCAEA,sCAGA,YAGA,UAUA,iCACA,SACA,CACA,QACA,aACA,SAGA,cAEA,4BAEA,oBAIA,wBAGA,kBAEA,yBACA,gBAGA,kBAEA,yBACA,gBAGA,QACA,QAaA,uBAEA,UAGA,aACA,QAMA,SAJA,cAKA,uBAGA,gCACA,uBAGA,wBACA,mBAGA,gBACA,QAQA,EACA,QAIA,cAOA,sBAQA,uBACA,cACA,cACA,cAEA,KAuBA,OACA,kBACA,YAGA,yBACA,aACA,oBAGA,KAsBA,QAEA,kBACA,4BAGA,oCACA,uBACA,sBAEA,SACA,OAEA,QAIA,CACA,QAoBA,WACA,kBACA,YAGA,yBACA,aACA,wBAGA,KAmBA,UACA,kBACA,YAGA,yBACA,aACA,uBAGA,KAYA,UACA,iBACA,WAEA,iCACA,mCAeA,0BAGA,wFACA,SACA,CAWA,WACA,iBACA,WAEA,yBACA,uDAEA,+CAEA,YACA,OAEA,QAAI,KACJ,WAEA,UACA,iBAGA,SACA,GAEA,QAGA,CACA,QASA,cACA,iBACA,WAEA,yBACA,uCAEA,sDAEA,WAGA,SASA,aACA,iBACA,WAEA,yBACA,0CAEA,qDACI,aACJ,WAEA,OACA,UAEA,SAEA,CACA,K9P/hBA,IAjBA,CACA,UACA,UACA,KA8EA,aACA,OAMA,YAIA,6HAIA,4EAEA,aACA,WAQA,EAvGA,aAwGA,eAEA,MACA,YAGA,iCAIA,6BAEA,WACA,WAMA,qBAJA,gCAKA,MAGA,uBACA,MAOA,EAtIA,gBAuIA,aACA,uBACA,KAQA,EA9IA,mBCgEA,QAQA,aAAgC,KAMhC,oBAIA,+DACA,oEACA,KAgBA,WAAuC,KACvC,WAEA,4BACA,yBAKA,mCAKA,+BAIA,gBAGA,SARA,MAcA,kBAAqD,KACrD,SAAyB,QACzB,CACA,eAGA,mBACA,gDACG,oBACH,kCAEA,qDAIA,qDASA,4HAEA,SAGA,QACA,MAMA,sBAAyD,KAEzD,sBAKA,iBACA,gBACA,kDACA,wBACA,SACA,6CAKA,4BACA,UAgDA,EAQ0D,SEzP1D,mBAUA,mBACA,IAEA,yBAMA,oBACA,QAwBA,0HAEA,uBACA,KAOA,SACA,MACA,eAkDA,EC1GA,SAkDA,QACA,mBAMA,MAOA,sBAOA,aAaA,oDAOA,6BACA,MASA,iBACA,SAEA,kBAAkB,MAAkB,WACpC,SAEA,wBACA,kBACA,iCAEA,QACA,CAQA,oBACA,aACA,8BAGA,sEACA,SAUA,iBAIA,SACA,kBAQA,iBANA,gCASA,wDAmBA,gBACA,iCAfA,0BAqBA,mBAEA,MACA,wCAIA,gBAEA,yBAMA,2BAEA,MACA,8BAIA,mCAAgC,0BAChC,4DACA,eAIA,uBAEA,yBAKA,WAEA,iCAGA,UAQA,eAPA,MACA,mFAAK,sBAGL,8CAKA,iCAEA,6BACA,wBAGA,cAGA,wDAH2D,0BAC3D,aAIA,IAMA,sBACA,IAIA,6FACA,kFACA,kBACA,qBAEA,oBACA,oCAEA,qBAIA,mBACA,sFAEA,wBACA,wBACA,QAEA,MAEA,eAIA,qBAKA,wIAIA,4DAEA,+BAIA,8EAEA,wBACA,wBACA,QAEA,GACA,WAIA,SACA,iFAEA,OAQA,0BACA,gBAKA,gDAGA,gDACA,iDAGA,4BACA,SACA,uBAGA,kBAOA,mCACA,4CAEA,WACA,GAGA,uCAEA,gDACA,MAGA,oCACA,uBACA,wBAIA,kBACA,oBAEA,SAAI,uBACJ,mDACI,YACJ,sCAEA,8BAEA,eAEA,+CACA,UACA,CAEA,CACA,QASA,mBACA,+BAIA,SACA,8BAGA,QACA,IAQA,qBACA,0BACA,MACA,8BACA,oBAEA,UAOA,kBACA,gCACA,MAMoB,EKxZpB,QAOA,iBAOA,MAQA,aASA,wBAeA,0CACA,aAEA,iDAAsD,UAetD,mCACA,UAQA,yCAA+C,UAC/C,8CAA6D,UAC7D,uDAAsE,UAEtE,WACA,2FACA,YASA,cAEA,kCACA,WAYA,aAEA,cAGA,gCACA,SAYA,UACA,YAEA,cACA,OAOA,mBALA,mCAEA,gCAEA,iBAaA,gBAEA,oBAEA,yCAGA,sBACA,uCAGA,mCACA,yBACA,0CACA,SACA,EAYA,mBAEA,wBAGA,sBACA,YAiBA,qBACA,mCAA2D,SAC3D,KAKA,WAWA,qBACA,IACA,WAkBA,qBACA,CACA,SASA,qBACA,IACA,SASA,sBACA,OACA,MAWA,cACA,IACA,uBAGA,eACA,YAGA,0BAEA,iEACA,MAIA,SACA,QACA,EsPzTA,SACA,QAKA,eASA,MA8CA,aAQA,SACA,YAEA,SAMA,sCAHA,mBAEA,OAQA,uBACA,OACA,kCASA,mBACA,mBACA,YChHA,EtPsBA,mCsPVA,WACA,sBACA,MAHA,6BAIA,ICRA,EvPgBA,aAEA,IuPjBA,WACA,sBACA,MAEA,KCJA,OCLA,GDMA,aACA,YACA,MAEA,OACA,YACA,UAGA,SACA,QAEA,EEfA,GDcA,qBACA,OACA,EAHA,MAIA,WAEA,qBACA,KAGA,iBACA,OACA,WAEA,aACA,EACA,SA/BA,EAiCA,oBAGA,gBACA,OACA,OAEA,KACA,WACA,EACA,eAEA,6BACA,CACA,KAEA,SACA,KACA,KAEA,CACA,4BACA,OACA,gBACA,uBAEA,MAAW,GACX,CACA,KACA,KACK,UACL,EACA,OACA,cACA,CACA,KACA,KACA,CACA,CAEA,SADA,cAGA,WCtDA,0BAmBA,eCzCA,GD0CA,uBACA,CACA,UACA,IAxBA,uCAyBA,4BACA,WAEA,aACA,WAEA,OACA,IAnCA,8CAoCA,wBAKA,WACA,IApDA,mBAwDA,IAvDA,0BAyDA,GACA,IAzDA,qDA2DA,QAEA,IA3DA,kCA6DA,SACA,IA7DA,kBAiEA,IA/DA,8BAiEA,GACA,IAtEA,kBAwEA,MACA,IAtEA,qBAuEA,EA9EA,SAgFA,sBACA,GAGA,iBAEA,gBAEA,MACA,GA5FA,IA+FA,iBAEA,eACA,IArFA,kBAsFA,4BAGA,SACA,QAEA,EE7GA,GDgBA,qBACA,OACA,EAHA,IAIA,UACA,SACA,UAEA,gBACA,GAEA,gBACA,OACA,UACA,kBACA,QAIA,iBACA,OACA,WAEA,SACA,QAEA,gBACA,YACA,GACA,WACA,OAEA,KACA,WACA,EACA,eAGA,kBACA,oBAEA,iBACA,CACA,KACA,KACA,OACA,iBACA,UACA,SACA,gBAGA,YACA,yBACA,2CACA,sCACA,kBAEA,KACA,CAEA,SADA,cAGA,QClDA,GAXA,4BACA,yBAWA,GAVA,yBACA,uBAUA,GATA,0BACA,uBASA,GARA,iCACA,wBAQA,GALA,2BAMA,GAhCA,yBACA,kBAgCA,GAnBA,2BAZA,oBAgCA,GAnBA,wBAZA,iBAgCA,GA/BA,qBACA,qBA+BA,GA9BA,mBACA,mBA8BA,GA7BA,sBACA,mBA6BA,GA5BA,mBACA,mBA8BA,GA5BA,uBA6BA,cAOA,gBAmBA,SC/DA,GDgEA,WACA,OACA,8BACA,QAEA,KCjEA,wBACA,oBAGA,4BAGA,gBAgBA,e5PnBA,G4PoBA,qBACA,OACA,QACA,MACA,KAGA,WACA,QAGA,kBACA,QAEA,0BACA,gBACA,QAEA,WACA,gBACA,WACA,MACA,gBAEA,yBAjDA,GAkDA,oBACA,8BAEA,uBACA,WACA,gBAEA,uBACA,QACA,YACA,CAIA,mBACA,QACA,gBAEA,ECnDA,MCTA,GDUA,aACA,OACA,QAEA,ECbA,mBAmBA,uBACA,CAQA,uBAQA,wBAQA,+BAQA,gCACA,MAKA,WACA,OACA,sBACG,eACH,qBAEA,kBAEA,iBAOA,QACA,oEACA,YAOA,cACA,gFACA,EAKA,WAEA,sCACA,4DASA,eAGA,iIAAM,gCAIN,8EAQA,UACA,QACA,qFAAM,iBAGN,KAGA,8BAEA,oDAGA,UAAU,oEACV,SAKA,uBACA,OACA,2CASA,qBACA,oEACA,YCrJA,EACA,mBAWA,qBACA,CAOA,gCAOA,2BAOA,iCAUA,2BACA,WAKA,WACA,OACA,MAOA,QACA,wFACA,aAGA,uBADA,UAiBA,qBACA,+EACA,QAOA,cACA,iFAEA,0FACA,GAGA,uBADA,UAMA,WACA,6BACA,6BACA,6BACA,6BAKA,cAMA,QACA,QAEG,4GAMH,eACA,QAEG,iHAMH,aACA,QAEG,wJACH,2FACA,yCAEA,wEAMA,aACA,QAGA,sGAGA,sFAEA,sBACA,qBACA,eAEA,QAKA,uBACA,OACA,sCASA,qBACA,uBACA,kCAEA,6CAEA,aAKA,SAJA,aAGA,cC9LA,EACA,mBAMA,eACA,aACA,cAKA,gBACA,MACA,gBAKA,WACA,OACA,UAOA,cACA,iFAEA,iFACA,EAKA,uBACA,OACA,0CC5CA,EACA,mBAIA,WACA,OACA,QAOA,cACA,iFAEA,iFACA,EAKA,uBACA,OACA,wCClBA,EACA,mBAQA,mBACA,CAQA,0BAQA,wCACA,MAKA,WACA,OACA,QAOA,QACA,2CAEA,+CACA,YAOA,cACA,qCACA,YAEA,kFACA,EAKA,WAKA,cACA,0CAEA,4BAEA,kBAAU,CACV,QAKA,uBACA,OACA,wCASA,qBACA,MAEA,uBACA,QAEA,eAGA,uBAIA,yDACA,YC9GA,EACA,mBAQA,uBACA,CAQA,cAQA,6CAQA,2CAQA,UACA,UAKA,WACA,OACA,QAOA,QACA,wEACA,YAOA,cACA,oFACA,EAKA,WACA,6BAEA,gDAEA,UAAU,gBACV,OAKA,SACA,eAEA,SAGA,gBADA,UAMA,uBACA,OACA,wCASA,qBACA,OACA,UACA,0CACA,0CACA,OACA,UAEA,YC5GA,EACA,mBACA,WACA,OACA,MAOA,QACA,oBACA,YAOA,cACA,gCACA,EAKA,WACA,CACA,QAKA,uBACA,OACA,oCCpCA,EACA,mBASA,qBACA,CAOA,cAOA,gBAOA,eACA,SAKA,WACA,OACA,QAOA,QACA,mFACA,YAOA,cACA,+FACA,EAKA,WAEA,uBAEA,eAMA,sBACA,QAEG,oIAMH,aACA,QAKA,qHAEA,sBAGA,SAAU,wBACV,QAKA,uBACA,OACA,wCASA,qBACA,+DACA,YC7GA,EACA,mBAWA,uBACA,CAQA,cAQA,YAQA,WAQA,gBACA,UAEA,WACA,OACA,sBACG,mBACH,qBAEA,sBAEA,qBAOA,QACA,mEACA,YAOA,cACA,+EACA,EAEA,WACA,kEASA,cAGA,qIAAK,yBAIL,iFAQA,UACA,QACA,yFAAK,yBAIL,YACA,qDAKA,0CAHA,UAGU,kEACV,SAKA,uBACA,OACA,+CASA,qBACA,iBAOA,WACA,QACA,2HAAK,CAIL,2EACA,YCtJA,EAEA,YACA,oBACA,oBACA,oBACA,oBACA,oBACA,oBACA,oBACA,oBACA,oBACA,MAMA,cACA,QAQA,qBACA,0BACA,aCpCA,EAEA,YASA,KACA,QAQA,qBACA,cAOA,kBACA,QACA,yEAAK,QAIL,+BAEA,eAEA,uBACA,6BAIA,wBACA,0BACA,qBAIA,MACA,QAOA,mBACA,UACA,YCnDA,EACA,QAIA,cAQA,YAQA,UACA,aASA,kBACA,OACA,6CAGA,YACA,IAKA,mBACA,qBACA,yBAEA,GAQA,yBACA,CACA,SAcA,gBACA,CAIA,eAHA,qBAEA,SAQA,QACA,kBAEA,gCACA,4BAGA,SACA,QAaA,cACA,kBAEA,uCACA,4BAGA,4BAEA,oBAAkB,iBAA6B,OAC/C,wFAGA,EACA,QAOA,SACA,YAEA,MAMA,sCAHA,mBAEA,OAUA,uBACA,OACA,0BACA,EAEA,GxQxIA,aACA,QAOA,2BAOA,MAQA,gBAYA,eACA,MASA,kBACA,wDACA,IASA,YACA,CAIA,eAHA,iBAEA,SAQA,iBACA,qBACA,eAEA,UAqCA,EClHA,mBAIA,WACA,OACA,WAQA,UACA,kDACA,IAQA,YACA,uDACA,IAQA,YAEA,SACA,mBAGA,aACA,OAEA,yBACA,WAIA,8CACA,oBAGA,oCACA,kBAIA,YACA,mBAEA,iBAGA,QACA,IAEA,yBACA,CACA,SAKA,SACA,eAEA,SAGA,gBADA,QAMA,uBACA,OACA,mCAUA,EACA,mBAIA,uBACA,OACA,uCAaA,EACA,iCACA,WAEA,YACA,IAWA,GACA,kCACA,kBAEA,QACA,IAAC,GAgGD,gBACA,GC7OA,aACA,mBAIA,WACA,OACA,MAOA,cACA,wDACA,IASA,qBACA,+DACA,IASA,qBACA,+DACA,IASA,qBACA,4BACA,IAKA,yBACA,CACA,SAKA,uBACA,OACA,8BACA,EAgBA,uBACA,SACA,eAEA,4BACA,OAMA,oBAGA,gGACA,SACA,mCAGA,WACA,KAAC,GAED,GCvGA,aACA,mBAIA,uBACA,OACA,gCACA,EAqBA,uBACA,oBAEA,kCAEA,mBACA,6CAEA,OACA,iCAGA,SACA,KAAC,GAED,GsQxCA,aACA,mBAIA,WACA,OACA,QAQA,eACA,6DACA,IAQA,YACA,0DACA,IASA,uBACA,4BACA,IAKA,yBACA,CACA,SAKA,uBACA,OACA,gCAaA,EACA,yBACA,SAGA,SACA,mBAGA,cACA,kCAEA,iBACA,cACA,8BAGA,kBACA,2CAEA,uBACA,QACA,eACA,wBAGA,wBACA,cAGA,OACA,KAAC,GAED,GCnGA,aACA,mBAIA,WACA,OACA,OAOA,eACA,+DACA,IAiBA,sBACA,4BACA,IASA,qBACA,+EACA,IAKA,yBACA,CACA,SAKA,uBACA,OACA,+BAYA,EACA,sBACA,SACA,YAEA,sBAEA,aAMA,oBAGA,4EAEA,mBACA,UAEA,+BAGA,WACA,8BAEA,0BAEA,uBACA,sCACA,iBAEA,kBAEA,cACA,8BAEA,kBACA,IAAC,GAED,GCjHA,aACA,mBAIA,WACA,OACA,OAQA,eACA,mEACA,IAYA,uBACA,4BACA,IAKA,yBACA,CACA,SAKA,uBACA,OACA,+BAYA,EACA,sBACA,SACA,YAEA,sBACA,eAEA,eAMA,8BAGA,sFAMA,8BAGA,sHACA,sCAEA,aAEA,WAEA,0BAGA,WACA,cACA,8BAEA,wCACA,YAEA,2CACA,kBACA,8BAEA,kBACA,IAAC,GAED,GvQ7GA,aACA,mBAIA,WACA,OACA,QAKA,yBACA,CACA,SAKA,uBACA,OACA,gCACA,EAeA,yBACA,MAMA,8BAGA,8GACA,YAEA,qEACA,mBAEA,UACA,IAAC,GAED,GwQrDA,aACA,mBAIA,WACA,OACA,MAOA,YACA,cAEA,kFACA,IAOA,cACA,cAEA,2CACA,CAUA,uBACA,4BACA,IAQA,qBACA,4BACA,IAKA,yBACA,CACA,SAKA,uBACA,OACA,8BAWA,EACA,uBACA,OAMA,oBAGA,mFAEA,aAMA,4BAGA,uEAMA,6BAGA,gGACA,YAEA,iDACA,WACA,8BAEA,yDACA,KACA,SACA,2BAEA,uBAEA,kBACA,8BAEA,kBACA,IAAC,GAED,GCjIA,aACA,mBAIA,WACA,OACA,QAOA,eACA,+DACA,IAQA,qBACA,4BACA,IAKA,yBACA,CACA,SAKA,uBACA,OACA,gCAUA,EACA,uBACA,IAMA,6BAGA,4FACA,YAEA,mDAEA,KAEA,WACA,aACA,8BAGA,WACA,cACA,8BAIA,wCACA,YAEA,4DACA,kBACA,8BAEA,kBACA,IAAC,GAED,GC5FA,aACA,mBAIA,uBACA,OACA,oCAsBA,EACA,6BACA,SACA,YAEA,cAEA,eACA,kDAGA,kDACA,kBACA,8BAEA,kBACA,IAAC,GAED,GC5CA,gB1QuCA,IA+eA,eAAqC,CAAkB,aACvD,OAEA,EACA,qBACE,gBACF,qBACE,mBACF,qBACE,uBACF,qBACE,gBACF,qBACE,gBACF,qBAEA,cAIA,SACA,oBACG,gBACH,oBACG,mBACH,oBACG,uBACH,oBACG,gBACH,oBACG,gBACH,oBAEA,cAIA,cAEA,qBACA,cAGA,EAxhBA,SACA,iBAGA,uBAEA,WAGA,gDAGA,wFAEA,aACA,GAEA,EAEA,sBAEA,0BAEA,mBAIA,uCACA,WAGA,gDAGA,0CACA,wBACA,iBACA,iBAEA,yBAGA,gBACA,GAGA,sBAEA,qBAEA,+DAGA,wCACA,4CAEA,aAIA,2BACA,kBAIA,4CACA,4CAIA,0CAMA,OAQA,aAPA,uDACM,cACN,4BAIA,MAGA,UAEA,QAEA,EAEA,0BAEA,mBAGA,qCAEA,0DAGA,YAKA,yBAGA,4BAEA,yBAKA,yEACA,kEAOA,gFAGA,WAIA,2DACA,kEAEA,wBAIA,eACA,4CAEA,aAGA,0BACA,CAEA,mBAIA,mDACA,mCACA,2DACA,YAKA,mBADA,aAGA,EAEA,mBAEA,mBAGA,kCAEA,qBAEA,WAGA,mFAEA,cACA,GAEA,EAEA,sBAIA,gDAEA,WAEA,gCACA,eACA,qBAEA,6BAIA,oBACA,GAEA,EAGA,qCACA,WACA,+BAEA,uGAEA,cACA,GAGA,mBAEA,qBAEA,WAEA,iBACA,gGAGA,MACA,gGAGA,IACA,GAEA,EAEA,sBAEA,0BAIA,yCAEA,WAEA,qBACA,UACA,sBAEA,8BAIA,oBACA,GAGA,oBAEA,WAEA,sBACA,8EACA,uBACA,mBAEA,eACA,8EACA,uBACA,mBAEA,OACA,GAGA,iBAGA,uBAEA,wDACA,gCAEA,iFAGA,iDAEA,qBACA,cACA,2BACA,sEACA,eAGA,iCAEA,SACA,GAEA,EAEA,sBAEA,0BAEA,mBAIA,uCAKA,0DACA,4DAIA,iBAIA,gCAIA,8CAGA,gCACA,wBACA,iBACA,iBAEA,yBASA,4BAGA,iBAUA,4CACA,mCACA,oCAIA,2BAGA,6GACA,0EAEA,cAMA,sCACA,mEACA,gEAEA,uBAGA,2EACA,kEAEA,yBAaA,qEAEA,iCAIA,wGACA,0EAEA,cAeA,WACA,qCACA,iBACK,yBACL,kBAMA,YAIA,UAEA,kCAEA,8DACA,kEAGA,iBACA,kIAEA,oBACA,KAGA,WAEA,uCAEA,qDACA,kEAQA,sBACA,eAGA,QACA,yDACA,SAEA,aAMA,mBAIA,MAGA,uBAGA,cACA,SAEA,O2QtiBA,I1QIA,eACA,QACA,MAEA,OACA,eAEA,OACA,QACA,MAEA,oBACA,OAEA,YACA,SACA,cAEA,KACA,QAEA,U0QFA,KzQfA,G0QHA,WACA,eACA,KAEA,ECYA,MChBA,GCDA,eACA,aACA,iBAEA,gBACA,OACA,QACA,MAEA,QACA,QACA,CAEA,ECZA,GFCA,eACA,IACA,YAEA,qBACA,MAEA,OACA,UACA,SAGA,gBACA,CAEA,EGlBA,GDGA,aACA,oBACA,WAEA,EEPA,GDCA,eACA,YACA,MAEA,OACA,cACA,MAGA,SACA,QAEA,EEfA,GDGA,aACA,YACA,MACA,SAEA,SACA,cAEA,UACA,QAEA,EEbA,GDAA,WACA,mBACA,OACA,KACA,CAEA,EELA,GDAA,aACA,UACA,MAEA,EEYA,GDHA,iBACA,QACA,EACA,KACA,SACA,OACA,SAEA,UACA,GAGA,oBAGA,WACA,KAEA,QACA,QApBA,MAqBA,KACA,OAEA,WACA,kBACA,OACA,SAEA,uBACA,WACA,QACA,KACA,QACA,iBAGA,SACA,OACA,KACA,aAEA,OACA,CACA,QAEA,qBCzCA,OACA,iBAEA,YCxBA,GCKA,GDQA,iBACA,SACA,OACA,MAEA,MACA,cAEA,SACA,eACA,OACA,aACA,cACA,QAEA,QAEA,QACA,aACA,GACA,aACA,KACA,SAEA,aACA,IAIA,OACA,OACA,WAEA,kBACA,qBA9CA,CAiDA,CAtCA,QAwCA,QACA,uBAdA,QAEK,QAaL,CACA,QAEA,EEnDA,GDAA,WACA,gBACA,KAEA,EERA,GDKA,aACA,wBACA,UACA,KACA,EAEA,EEXA,GDCA,WACA,QACA,YAEA,MAIA,4BAHA,QACA,KACA,IAGA,KCDA,WACA,mBACA,OACA,YACA,IAbA,eAeA,MACA,GARA,eAUA,WACA,KACA,CCAA,CClBA,KCDA,GDEA,WACA,WACA,UAEA,OACA,qBAEA,IACA,QAEA,EEVA,GDDA,aACA,mBACA,OAGA,UACA,2BACA,WACA,CAEA,E3RhBA,G4RQA,WACA,OACA,+BACA,mBAEA,eACA,eACA,SACA,CAEA,K5R2BA,sBAsBA,GAEA,S6RpEA,aAIA,0BASA,gBCKA,GDJA,WAEA,IACA,mBAEA,YACA,2BAEA,WACA,0BApBA,GAqBA,MAEA,EE1BA,GDmBA,WACA,mBACA,KAEA,KCpBA,yEASA,4BACA,IACA,MAIA,yCAHA,6BACA,KACA,ICZA,GCLA,GDMA,WACA,gBACA,KAEA,KCTA,sDASA,QCXA,GDYA,aACA,IACA,MAEA,eACA,yCACA,uBAGA,uBACA,sBACA,UAEA,EEjBA,GDCA,WACA,wBACA,MAEA,iBACA,0BANA,GAOA,MAEA,EEMA,GDdA,aACA,eAEA,gBACA,MAEA,gBACA,cAEA,iBACA,aAEA,EEjBA,GDoBA,eACA,sBACA,cACA,eAEA,EEfA,GDTA,aACA,YACA,UAEA,EEgBA,GDVA,eACA,eAEA,iBAEA,MAEA,OAHA,SAIA,UACA,sBACA,QAEA,QACA,IACA,CACA,KAEA,0BACA,oBACA,wBACA,MAEA,EE/BA,GDoBA,aACA,iBACA,UAEA,EElBA,GDKA,aACA,eACA,SAEA,oBACA,OACA,2BACA,MACA,sBAlBA,CAmBA,CAVA,EAWA,CAEA,EExBA,GDQA,WACA,CACA,QAEA,EEMA,GDjBA,WACA,mBACA,OACA,QACA,CAEA,EEHA,GDeA,WACA,wBACA,KAEA,EEAA,GDlBA,WAGA,OAGA,uBAGA,WACA,mBACA,gBACA,IAEA,MACA,KAEA,qBCEA,OACA,YACA,SAEA,UACA,yBAEA,SCZA,sBACA,OACA,YACA,SAEA,UACA,gBAEA,qBCRA,GCAA,GDCA,eACA,kBAIA,8BACA,eACA,UAEA,EEzBA,GDgBA,eACA,kBAIA,8BACA,QACA,eACA,QAEA,EEAA,GDzBA,iBACA,aACA,cAEA,SACA,UAEA,kBACA,kBACA,kBACA,MAEA,EErBA,GCKA,eACA,CASA,MARA,SACA,eAEA,UACA,eAGA,YAGA,ECTA,GFqBA,WACA,qBAFA,YAGA,CAEA,EGNA,GDlBA,iBACA,SAEA,aACA,MACA,eAEA,yBACA,MACA,MAEA,cACA,MACA,OAEA,OACA,QAEA,EEMA,GC3BA,eACA,aACA,cAEA,QACA,YACA,UAGA,gBACA,CAEA,ECPA,GCGA,WACA,sBACA,SAEA,ECdA,GCYA,eACA,WACA,eACA,WACA,OACA,MACA,WACA,SAEA,UACA,OACA,KACA,cAEA,eACA,+BACA,sBAEA,YACA,KAEA,UACA,MAEA,GACA,8BACA,OACA,SAEA,uBACA,EACA,GACA,SACA,SACA,KACA,SACA,OACA,QACA,GACA,WAEA,kBAEA,MAEA,MAEA,UACA,OACA,CACA,CACA,QAEA,ECnDA,GFbA,WACA,OACA,WAEA,mBEUA,OACA,mCACA,GAEA,QCGA,oBACA,OACA,QAEA,oBACA,MAEA,WAEA,yBACA,QAEA,SCfA,oBACA,OACA,QAEA,oBACA,MAEA,WAEA,yBACA,GAEA,iBCtCA,YAGA,gBAgBA,KCGA,GCbA,aACA,SACA,OAGA,qBACA,UACA,WAEA,ECbA,GCIA,iBACA,aACA,MAEA,OACA,YACA,QAGA,gBACA,CAEA,WDbA,gBAYA,OEAA,GFCA,iBACA,OACA,WACA,MACA,OAGA,mBAEA,QACA,iBACA,IACA,SAEA,QACA,kBACA,mBAEA,eAGA,GACA,QAEA,EGpBA,GDJA,aACA,0BACA,OAEA,SAEA,KEFA,OChBA,GCAA,aACA,YACA,MAEA,SAEA,SACA,YAJA,oBAMA,MACA,QAEA,ECdA,GFGA,aACA,mCACA,GAEA,WEJA,gBAUA,OCZA,GDaA,aACA,sBACA,MAEA,OACA,OACA,oBACA,IACA,QACA,kBAEA,oBACA,OACA,QAEA,QACA,qBAEA,OAEA,eAEA,MACA,CACA,CACA,QAEA,EEjBA,GDtBA,aACA,UACA,OACA,aACA,WACA,QAEA,QACA,aACA,WACA,QAEA,qBACA,kBACA,IACA,SACA,OACA,SAEA,kBACA,kBACA,IACA,SACA,OACA,UAEA,CACA,OACA,EAEA,qBCPA,QAEA,oBACA,IAEA,QAKA,4BAJA,gBACA,IAAG,GAEH,WCXA,YC3BA,gBAwBA,QCvBA,GCkBA,iBACA,GAEA,eACA,eACA,IACA,QACA,WACA,QAEA,gBACA,gBACA,OACA,QACA,aACA,WACA,QAEA,MACA,WAEA,kBAEA,kBAEA,oBACK,IAGL,eAGA,UAEA,EAEA,GACA,OACA,MAzDA,WAkBA,EAyCA,EC1CA,GFDA,eACA,OACA,QAEA,0CAlBA,aAaA,EAMA,WACA,aACA,IAEA,gBACA,eACA,SAEA,EAEA,GACA,CACA,QACA,OACA,aAEA,EGzBA,GCLA,aACA,YACA,MACA,SACA,EAEA,YACA,OACA,SAEA,uBACA,IACA,kBACA,GACA,CACA,CACA,QAEA,mCCfA,aACA,OACA,UCRA,ECOA,UAEA,CAEA,ECEA,GFFA,eACA,QACA,EACA,SACA,OACA,KACA,KAEA,IACA,KACA,KAEA,gBAbA,IAcA,cACA,MACA,WAEA,OACA,KACA,OACA,MAEA,QAEA,OACA,kBACA,OACA,SAEA,uBACA,WACA,aACA,OACA,QACA,iBAIA,YAEA,UACA,OACA,KACA,YACA,SAEA,UAEA,QACA,CACA,QAEA,mBEjDA,gBACA,SCOA,oBACA,OACA,YACA,SAEA,2BACA,MCVA,oBACA,OACA,YACA,SAEA,kBACA,kBCdA,GCSA,GClBA,aACA,YACA,MACA,SACA,EAEA,YACA,OACA,KACA,aAEA,OACA,CACA,QAEA,ECAA,GFIA,WACA,WACA,QAEA,eACA,2BACA,IACA,MAGA,cAFA,YAGA,mBACA,aACA,MACA,EAEA,EGtBA,GDGA,aACA,WACA,QAEA,eACA,YAGA,2BACA,OACA,eACA,EAEA,qBCfA,OACA,OAEA,UCbA,GCUA,GDTA,eACA,YACA,MAEA,OACA,aACA,EACA,QACA,aAEA,aAEA,wBACA,YAEA,mBCLA,WACA,SCKA,oBACA,OACA,YACA,SAEA,sBACA,MCVA,oBACA,OACA,YACA,SAEA,aACA,kBCbA,MCXA,OCUA,GDTA,eACA,YACA,MACA,WACA,OAEA,YACA,WACA,gBACA,OACA,CACA,QAEA,EELA,GCAA,iBACA,eAEA,iBACA,MACA,OAGA,oBACA,UACA,eACA,IACA,aANA,EAOA,OACA,SACA,gBACA,eACA,eAGA,YACA,CACA,SACA,GACA,IACA,CACA,QAEA,mBCtBA,SACA,iBAEA,2CACA,gBACA,OCoCA,MAGA,OjGtCA,eACA,gBACA,YAEA,WAEA,oBACA,SACA,IAEA,mBACA,IACA,aAEA,MACA,mBAEA,MACA,QkGjCA,UACA,WACA,YACA,eACA,IACA,EAEA,YACA,OAEA,WAEA,OACA,CACA,QAEA,ShGHA,UACA,qBACA,qBACA,eACA,GAEA,IACA,YAEA,mBACA,2BAEA,ME/BA,gB6F4DA,sEvD7BA,aACA,aACA,iBAEA,YyDLA,EF+BA,UE9BA,aACA,aACA,iBAEA,SAEA,OrDbA,iBACA,kBAIA,mCACA,cACA,EAEA,KACA,eEjCA,YD6BA,aACA,aACA,iBACA,KACA,CqDLA,gBACA,aACA,aACA,iBACA,QACA,CAEA,WH0BA,QhDtDA,WACA,kBACA,gBACA,KoDhBA,cAgBA,WACA,kBACA,WACA,OAJA,KCIA,eACA,aACA,kBAIA,2BACA,MACA,WChBA,YACA,WACA,YACA,eACA,EAEA,YACA,OACA,eACA,EACA,CACA,QCGA,UP2CA,QO1CA,eACA,kBAEA,cAGA,MACA,eAEA,IACA,YALA,CCnBA,UACA,WACA,aACA,EAEA,wDRoDA,KzCnDA,aACA,uBACA,EkDIA,sBACA,eACA,kBACA,KACA,UAEA,KACA,QACA,eACA,QACA,CACA,WACA,UACA,IAEA,GACA,YAEA,iBACA,QACA,SAGA,gBACA,CAEA,MjD7BA,aACA,yBACA,aGjBA,UqCgEA,qBlC9CA,eACA,0BACA,cAEA,Q4CPA,cACA,eACA,0BACA,OAEA,kBAEA,mBtCCA,aACA,IACA,gBACA,QAEA,gBACA,EACA,SAEA,kBACA,UACA,OACA,KACA,aACA,UAEA,QACA,CAEA,MADA,UCjDA,E2ByEA,Q3B7CA,WACA,aACA,SsCZA,QACA,eACA,kBAIA,mCACA,aACA,EAGA,kBACA,qBAEA,OACA,aAEA,cnCdA,aACA,OACA,QoCIA,gBACA,eACA,eACA,MCbA,gBACA,aACA,kBACA,OACA,OACA,mBACA,QAEA,QACA,QACA,CCTA,EdwDA,gBcvDA,aACA,OACA,WCCA,oBACA,eACA,eACA,SCRA,oBACA,aACA,kBACA,OACA,kBACA,QACA,QAEA,QACA,QACA,CAEA,avCbA,WACA,aACA,OAEA,QwCHA,eACA,aACA,aACA,YAEA,SCRA,ElB6DA,KkB5DA,WACA,aACA,ECSA,OACA,eACA,aAGA,0BACA,iBACA,QCPA,YACA,eACA,kBAIA,8BACA,QACA,aACA,UCEA,iBACA,aACA,aACA,iBAEA,YCLA,YACA,aACA,aACA,iBAEA,MAEA,EtBgCA,sCf1DA,WACA,aACA,OAEA,QsCCA,SACA,aACA,aACA,YAEA,SCTA,ExB0DA,SwBzDA,aACA,aACA,OAEA,iBAEA,0CxBoDA,qCJ5DA,aACA,iBACA,SELA,gBDEA,aACA,iBACA,SEEA,E0B2C6B,YjYvC7B,YAKA,QAuBA,iBACA,2CAGA,gCACA,sCAEA,kBACA,QAaA,yBAGA,MAGA,cAGA,WAGA,iCAGA,SAGA,aAEA,kBAAoB,MAAgB,WAEpC,SAkBA,OAKA,+CAEA,uBAIA,iBACA,2BACA,0DAGA,qBAIA,+BACA,UAYA,CACA,IAIA,cACA,UAKA,OAEA,aACA,cASA,8BACA,UAGA,gBACA,QAGA,YACA,QAQA,4BACA,gBAIA,0CACA,YAEA,gBACA,wDACA,MAEA,OACA,KAEA,CAGA,kBAIA,mBAkBA,gCACA,eACA,gBAEA,UAEA,WACA,CAGA,kBACA,kBACA,wBACA,OACA,aAEA,qBACA,wBAEA,QAEA,WAAkB,MAA+B,WACjD,UAEA,gBAAmB,MAA+B,WAClD,UAEA,gBAAoB,MAAmB,OACvC,cAAqB,MAAmB,WAExC,YAGA,uCACA,gBACA,8BACA,0BACA,2BACA,2BAGA,oCACA,iBACA,8BACA,2BACA,2BACA,2BAGA,gBACA,IAEA,sCAEA,eACA,wBAEA,QAEA,cACA,kBAEA,eACA,kBACA,CAGA,cACA,kBACA,CAEA,cACA,kBACA,CAEA,eACA,cAEA,YACA,UACG,KACH,UAGA,KAAU,WACV,UAGA,MAEA,OCxSA,mBAIA,WACA,OACA,QAQA,yBACA,CACA,SAKA,uBACA,OACA,gCAoBA,EACA,4BACA,gCACA,6BAEA,cAMA,gBAGA,0GAKA,iBAMA,sBAHA,QAIA,IAQA,GACA,6BACA,gCAEA,+BAMA,oBAGA,oHAEA,8BAEA,MACA,IAAC,GAaD,GCzHA,aACA,YACA,4BA2BA,iBACA,kBAGA,SAEA,UAKA,kCAJA,kBAGA,UAGA,GACA,kBAEA,OACA,eAGA,qBACA,2DAEA,MAGA,oBACA,+BAGA,0BAGA,oEACA,SAEA,wBACA,QACA,kCAEA,6DAEA,oBACA,OACA,cACA,eACA,SACA,SAGA,MAEA,QACA,KAGA,CACA,QAEA,GACA,kBAEA,OACA,eAGA,qBAKA,wCACA,UACA,GACA,gBAIA,SACA,SAAC,GAiBD,aACA,aACA,aACA,aACA,aAGA,aACA,kBACA,WAGA,kBACA,eAMA,gBACA,qCACA,MAEA,mKAEA,aACA,MACA,GACA,gBAIA,SACA,SAEA,GACA,kBAEA,OACA,eAGA,qBAIA,wCACA,WAGA,MACA,SAEA,GACA,kBACA,WAGA,kBACA,eAKA,gBACA,qCACA,MAEA,mKAEA,aACA,OAGA,MACA,SAAC,GAED,kBACA,WAGA,SACA,WAIA,8BACA,eAGA,8BACA,6BAGA,qDACA,sBAEA,8FAIA,oCACA,wGAEA,yCAKA,2EACA,qEAEA,aAEA,uBAEA,WACA,gCAGA,aACA,oBACA,wDAEA,qBAGA,UACA,GAAG,KAGH,gBACA,sBACA,cAEA,gBACA,SAGA,OACA,UAEA,GACA,SAEA,WACA,2CAMA,wDAGA,MAGA,UAPA,WAQA,kBAEA,OACA,eAMA,kDACA,UACA,8IAEA,UACA,YACE,qFAIF,WAOA,wCAGA,6BAGA,0BACA,qBAKA,sBAEA,6CACA,yBAKA,4BACA,yCACA,oBAEA,iBACA,GAEA,OACA,UAEA,GACA,kBAEA,OACA,eAGA,eAEA,kBACA,2DAGA,cACA,qCAKA,qBACA,oEACA,CACA,uEAKA,6DAHA,UAIA,KAGA,OACA,GAEA,GACA,SAEA,WACA,2CAMA,uDACA,GACA,gBAIA,SAGA,UAVA,WAWA,gBAEA,YAEA,SAKA,kCAJA,kBAGA,UAGA,GACA,kBAEA,OACA,eAKA,kDACA,UACA,8IAEA,UACA,WACA,GACA,gBAEE,wFACF,WAGA,2CAGA,0BAGA,2FAEA,KACA,GAEA,OACA,UAEA,GACA,kBACA,WACA,WAGA,oBACA,+BAGA,0DAEA,6CAGA,WACA,gDAEA,KACA,OAEA,CACA,QAEA,GACA,kBACA,KAEA,kBAGA,mBACA,qCAGA,qDAGA,iDACA,WACA,uDACA,8DAEA,KACA,KAEA,OACA,GAEA,GACA,kBACA,SAEA,0DAGA,kBACA,SAGA,qBAGA,SACA,KAIA,kBAEA,2BACA,WACA,iDAEA,WACA,wBAEA,EAGA,CACA,QAEA,GACA,kBACA,WAGA,SACA,WAQA,iEAGA,kBACA,SAGA,eACA,kBACA,iDAEA,kBACA,wBAGA,GACA,SAGA,GCviBA,mBASA,0BACA,CAQA,cAQA,YACA,UAUA,eACA,aACA,IAKA,QAEA,gDAIA,gCAFA,KASA,SACA,aACA,Q+X7DA,EACA,QAIA,cAOA,MASA,kCAYA,wBAQA,2BACA,IAOA,YACA,mEACA,sBAEA,YACA,uCACA,cACA,CAWA,qBAEA,IAKA,oCAGA,iBAKA,iCACA,sBAEA,UACA,eAGA,MACA,OACA,EAQA,YACA,6BAEA,mCACA,UASA,sBACA,iBACA,4BACA,MAQA,kBACA,wBACA,MAQA,iBACA,2BACA,MASA,kBACA,wBACA,MAQA,aACA,6BAGA,qBACA,0CACA,gCAEA,eAEA,YAQA,eACA,mFAEA,CACA,QACA,E9XzKA,mBAMA,iBACA,CAEA,mBACA,KAOA,SACA,MACA,eA4EA,ECvGA,SCWA,QAQA,iBAOA,MAQA,2BAQA,0BAGA,aAEA,cAcA,aACA,0BACA,0CAEA,0CACA,KAEA,OACA,KAWA,YACA,0BACA,0CAEA,4CACA,GAEA,OACA,KASA,kBACA,sBAEA,eACA,wBAIA,WAOA,iBACA,qBACA,MAQA,iBACA,+BACA,kBASA,WACA,uBACA,WACG,YACH,oBAGA,kEACA,OAGA,qCACA,IAEA,uBACA,wBACA,CACA,KACA,KAGA,IACA,GAEA,QAEA,CACA,QAOA,aACA,qBACA,iBAEA,kBAYA,gBACA,OAEA,yBACA,gCACA,UAIA,oCACA,IAYA,eACA,OAEA,yBACA,6BACA,QAIA,oCACA,IAWA,mBACA,cAEA,wDACA,IAWA,kBACA,cAEA,qDACA,IAkBA,iBACA,MACA,uCAEA,4BAA8B,CAC9B,iBAOA,kBACA,CACA,6BACA,4CAA+B,CAE/B,kBAaA,kBACA,SAGA,4BACA,MACA,8BAGA,wHACA,QAEA,WAGA,8BAIA,gBAEA,4BACA,aAGA,uCAEA,4BAA8B,CAC9B,kBAUA,SACA,CACA,+CACG,YACH,+BACG,KAEH,UAGA,6BAEA,WAOA,SACA,oBACA,aAOA,SACA,oBACA,aAYA,oBACA,YACA,gBAEA,2BACA,IASA,kBACA,cAEA,mBACA,0BAEA,aASA,gBACA,cAEA,kBACA,0BAEA,aAYA,iBACA,IAMA,wBACA,QAIA,qHAEA,iBAIA,gDAEA,oBACA,aAGA,YACA,yCAEA,8BAEA,aAQA,gBACA,oBACA,MAUA,gBACA,oBACA,SAOA,mBACA,oBACA,MAQA,gBACA,oBACA,MAUA,kBACA,uBACA,gCACA,oBAEA,qCAAmC,iBACnC,iBACA,CAWA,mBACA,MACA,8BAEA,uCAAmC,mBAEnC,kBAYA,kBACA,MACA,kCAEA,sCAAmC,mBAEnC,kBAWA,mBACA,MAEA,wBAEA,oEAEA,mBAEA,sBACA,cAIA,eAEA,sCAAmC,6BACnC,iBACA,CASA,qBACA,IACA,0BAGA,mBACA,0BACA,kBAEA,0CACA,IA8BA,qBACA,YAEA,yCACA,cAGA,aAGA,0BACA,uCACA,kBAIA,mBAGA,+BACA,eAEA,QACA,CAaA,0CACA,YACA,4BAEA,gCACA,uCACA,kBASA,8BACA,YACA,MAGA,SADA,UAUA,cACA,MACA,8BAGA,mGACA,oCACA,mBAQA,eACA,WAAkB,iBAAyB,OAC3C,6BAQA,iBACA,QACA,6GAAM,qCAIN,YAOA,YACA,cACA,KAQA,mBACA,MACA,4BAEA,WAwBA,EAKA,SCvvBA,SAEA,mBA0BA,0HACA,mBAMA,eACA,CAQA,aAYA,uCAEA,sDAGA,IACA,aAKA,kCACA,UACA,EAKA,kBACA,sBAEA,wEACA,WAKA,aACA,wDACA,KAKA,YACA,uDACA,GAKA,iBACA,gDACA,CASA,kBACA,OACA,sBAKA,UACA,WAAkB,iBAAyB,OAC3C,oBAGA,cACA,eAKA,aACA,cACA,mBAEA,iCAEA,kBAKA,gBACA,8CACA,kBAKA,eACA,6CACA,kBAKA,iBACA,OACA,mBACA,mBAKA,kBACA,OACA,uBACA,mBAKA,kBACA,OACA,oBACA,mBAKA,kBAEA,yCACA,cAGA,6CAEA,8BACmC,eAAnC,IACA,iBACA,CAKA,mBAEA,yCACA,cAGA,mDAEA,8BACmC,eAAnC,IACA,iBACA,CAKA,mBACA,GAEA,0CACA,cAGA,uCAEA,gCAEA,eACA,qCAAmC,iBACnC,iBACA,CAKA,kBACA,MACA,mBAKA,oBACA,MACA,qBAOA,6BAUA,cACA,mFAKA,YACA,oBACA,QAKA,cACA,cAIA,iCAEA,OAUA,iBACA,MAMA,8BAGA,wHAMA,UAKA,oBAHA,iHAKA,0BAEA,mBAWA,+CATA,wBACA,2CAIA,yCAA+B,CAC/B,iBAEA,IAUA,qBACA,gBACA,sCAEA,iBAEA,gCACA,oBAGA,gCACA,mBACA,uBACA,kCAKA,gBAGA,4BAIA,4BACA,4BACA,cAKA,iBACA,aACA,mBAKA,QACA,yCAAmC,iBAEnC,iBASA,gCACA,OACA,KASA,+BACA,UACA,cAaA,wBACA,oBAEA,mBAEA,yCAGA,uBAGA,sBAIA,qBAGA,iCAGA,YAaA,yBACA,oBAEA,sBAMA,oDAIA,8BAGA,kCAGA,YAYA,yBACA,YAEA,2BAEA,kBAKA,iBACA,yBAIA,0BAEA,cAGA,0BAEA,MAEA,CACA,QAQA,wBACA,iCAEA,8BACA,yBACA,uCACA,qBAEA,kBACA,gBAGA,CAQA,0BACA,YAEA,4EACA,SASA,qBACA,YAEA,yEACA,WAQA,0BACA,qBACA,wBAEA,mDACA,YAEA,2BACA,oBAEA,oBACA,YAEA,2BACA,mBACA,CAUA,4BACA,cACA,oCAEA,aAEA,0BAEA,cAGA,iCAEA,+CACA,MAKA,sBACA,mBAEA,gBACA,CAAG,KAGH,iCACA,qCAGA,eAIA,YAIA,OACA,UAEA,QACA,QACA,kBAKA,SACA,UAEA,QACA,QACA,cAMA,iBAEA,uBAEA,CACA,QASA,4BAGA,YAGA,uCAIA,2CACA,oCACA,KAGA,WAEA,cAGA,uCACA,IAIA,0BAA8B,CAC9B,iBAYa,ECzpBb,QAIA,cAQA,iBASA,oBAQA,oBAQA,8BAGA,uBACA,2BACA,4BACA,qCAEA,sBAAe,sBACf,qBAAe,uBAEf,2BAMA,8CACA,oBAAe,uBACf,oBAgBA,SACA,gEACA,WAQA,YACA,mEACA,WAgBA,uBACA,kBACA,oBAoCA,SACA,oBACA,MAIA,cACA,YAKA,sCAIA,6BARG,6CAWH,gDACA,UAIA,kEACA,YAIA,0BACA,oBACA,8BACA,gBAWA,qCAIA,UACA,wBAGA,YAEA,eACA,2CACA,CACA,KACA,KAKA,IACA,GAEA,QAEA,CACA,QAQA,WACA,oBACA,MAWA,kBACA,SAMA,wBAGA,8FACA,wBAIA,qGAOA,sEACA,0BACA,QASA,iBACA,4BACA,wBAGA,0GAEA,0BACA,KAaA,+BACA,MAEA,8BAAuB,0CACpB,mBACH,WAGA,qBACA,yBAEA,sBAIA,gDAEA,wBAAuB,kCAEvB,eAEA,QAEA,CAGA,CACA,QASA,oBACA,MAEA,uBACA,SACA,UACA,gBAEA,iCACA,sBACA,4BAEA,iBAAuB,iBACvB,oBACA,mBAGA,iBAGA,kBACA,YAEA,OACA,mBAEA,YAEA,CACA,QASA,mBAEA,oBACA,oBAEA,+BAII,uBADJ,oBAGA,8BACA,SACA,YAMA,OACA,QAYA,kCACA,kBACA,gCACA,oBACA,yBAGA,sCAAsB,qBAGtB,4BACA,8BAAwB,qBAExB,iBAEA,uBAMA,yBACA,uEAEA,QACA,CAUA,YACA,UACA,wBAGA,+FACA,MASA,8BACA,IAEA,SACA,eACA,QACA,yBACK,MACL,SAGG,gCACH,aAEA,OACA,mBACA,UAGA,SACA,SAAG,KACH,mBAGA,MACA,QASA,EACA,QAMA,eAOA,MAQA,eAQA,iBAQA,oBACA,sBAQA,WACA,eACA,eAQA,cACA,eACA,kBASA,qBACA,0BACA,OAOA,SACA,YAGA,MAGA,iBADA,kBAWA,gBACA,KAEA,QACA,UAGA,cACA,qBAAyB,QAEzB,aAUA,eACA,wCACA,YAEA,cACA,UACA,wBAIA,MACA,QAUA,4BACA,IAEA,8CACA,CAEA,cACA,4BACA,CACA,KACA,KAGA,CACA,KAEA,KAEA,CACA,QAWA,wBACA,cAEA,wBACA,mBACA,aAIA,SACA,QAmC0B,ECrrB1B,QAIA,cAOA,kBACA,IAOA,oBACA,sBACA,QAQA,OACA,sBACA,MASA,OACA,8BACA,IAgBA,SACA,2BACA,uBAEA,YACA,WAEA,gBACA,WAGA,cACA,SAEA,YACA,qBAEA,YAIA,qBAHA,mBAEA,aASA,UACA,2BACA,uBAGA,iCACA,oBAEA,oBAMA,qBAQA,yBACA,eACA,mBACA,sBAGA,QAKA,UACA,8BACA,cAGA,gCAEA,UACA,eAeA,oBACA,8BACA,6BACA,OAGA,QAQA,kBACA,GACA,6BACA,sBACA,IAeA,EA+BA,SACA,QAOA,iBAOA,MAQA,YAGA,yDACA,oDACA,KAOA,WACA,UACA,wBAGA,0GACA,MAOA,SACA,UACA,wBAGA,0GACA,IAcA,WACA,UACA,wBAGA,4FACA,WA6BA,ECrTwD,SAExD,SAcA,aACA,QAKA,cAUA,cAOA,cAUA,2BAQA,mBAQA,6BAQA,WASA,iCAGA,0CACA,+BACA,qBAQA,gCACA,iHAA8E,CAG9E,SAGA,mBACA,WAQA,gBACA,aACA,WAUA,kBACA,yBAOA,aACA,QACA,sGAAK,CAGL,wBAEA,gBAEA,kCAEA,yDACA,KAQA,SACA,eACA,OAWA,+BACA,eAQA,YACA,QACA,kFAAK,CAIL,wBACA,UAGA,kBADA,UAMA,UACA,gBACA,eACA,eAaA,kBACA,yBAEA,uCACA,2BACA,6BACA,0BAGA,kBACA,cACA,CAQA,kBACA,gBAOA,YACA,QACA,kFAAK,CAIL,2BACA,MAQA,WACA,mBACA,MAOA,eACA,kDACA,MAqBA,qCAEA,sBAA2B,cAC3B,iBAGA,iBAEA,cACA,0BAAqC,2BAGrC,0BACA,yBAAoC,CAGpC,0CACA,kCACA,mBAEA,mDACA,2BAGA,2BAA4B,uBAC5B,+BAEA,aAEA,OACA,KAkBA,0BACA,yCACA,KAOA,SACA,YAGA,MAGA,mBADA,oCAUA,kBACA,2BACA,qBACA,UAIA,qBACA,SASA,mBACA,cAGA,oBACA,qBAGA,sCACA,SAUA,2BACA,0BACA,IA8CA,EAKA,SCzbA,QAMA,eACA,wDAQA,4EAEA,2BAQA,iCAQA,sBAMA,0CAQA,4BAmBA,gBAQA,6BAWA,mBAcA,gBAOA,cACA,gBAkBA,iBACA,OAIA,iBACI,mBACJ,UACA,SAzBA,YAEA,wBAQA,eACA,uBAEA,sCACA,SAEA,CAbA,QACA,SACA,qBAEA,kCAEA,gBAwBA,UACA,kBAEA,gBAEA,8BAEA,uBACA,mBACA,eACA,oBACA,SACA,EAYA,cACA,uBACA,KAUA,iBACA,yBACA,YAEA,SACA,IACA,uBACA,QACA,oBACA,QACA,QAEA,OACA,EACA,ECzMA,SCoBA,SAAkC,SAiBlC,eACA,WAIA,GACA,uCAIA,6BACA,OAmBA,qBACA,WAGA,YACA,cAGA,uBACA,GAGA,SACA,IAGA,wBACA,OASA,qBACA,eACA,MAGA,OA+BA,OACA,QAKA,eAEA,QAGA,YACA,UACA,EAEA,mBAyBA,QAAkC,KAElC,eAIA,uCAIA,yDAGA,mDAEA,iBACA,qBAKA,uBACA,mBAUA,UAEA,aAEA,aAMA,4DACA,8BAEA,gBAeA,yBACA,cACA,MACA,SAKA,EAMA,4BALA,eACA,uCACA,gBAEA,GAQmB,IChPnB,QAIA,cAOA,uBACA,UAOA,YAUA,4CACA,iCACA,QACA,EAeA,SAAuC,KACvC,SACA,UAIA,qEACA,SAGA,GACA,mBAIA,oBACA,MAGA,KACA,SAAG,EAAG,CACN,YAQA,SACA,yCACA,QAKA,UACA,gBACA,eqXxFA,EACA,mBAMA,eACA,CAQA,aACA,QAmBA,SAAuC,KACvC,uBACA,MAEA,cACA,aACA,WACA,GACA,CAEA,OACA,UACA,EnXrCA,QAQA,iBAOA,MAQA,gBAQA,2BAQA,oCAGA,WAEA,cAeA,cAAoC,KACpC,MACA,iDAEA,aACA,SAQA,aACA,aACA,OAQA,yBACA,aACA,mBAWA,aACA,kBACA,aAEA,+CACA,qCAEA,gBACA,qBAQA,YACA,kBACA,aAEA,+CACA,uCAEA,cACA,qBAQA,kBACA,6CACA,WAOA,iBACA,qBACA,MAOA,iBACA,+BACA,kBAQA,sBACA,aACA,mBAGA,gBACA,IAkBA,cACA,MACA,8BAGA,qDACA,uCACA,aACA,SAOA,aACA,qBACA,iBAEA,kBAUA,gBACA,OAEA,yBACA,gCACA,UAIA,oCACA,IASA,eACA,OAEA,yBACA,6BACA,QAIA,oCACA,IASA,mBACA,cAEA,wDACA,IASA,kBACA,cAEA,qDACA,IASA,WACA,mBACA,OAGA,oDACA,mBAGA,+BACA,WACG,YACH,oBAGA,kEACA,OAGA,qCACA,IAEA,uBACA,wBACA,CACA,KACA,KAGA,IACA,GAEA,QAEA,CACA,QAUA,aACA,uBACA,WAGA,yBACA,oBAGA,gBACA,KAIA,YACA,KAIA,uCACA,KAEA,gBAEA,qBACA,mBAEA,4DACA,CACA,KACA,KAIA,IACA,GAEA,QAGA,CACA,QAOA,kBACA,cACA,cACA,qBAEA,UAYA,eACA,MAEA,4BACA,MACA,8BAGA,qDACA,aAEA,0BACA,aACA,SAUA,SACA,CACA,gCACA,mCACA,mDACG,aACH,+BACG,KAEH,UAGA,6BAEA,WAOA,SACA,oBACA,aAOA,SACA,oBACA,aAYA,oBACA,YACA,gBAEA,2BACA,IASA,kBACA,cAEA,mBACA,0BAEA,aASA,gBACA,cAEA,kBACA,0BAEA,aAYA,iBACA,IAMA,wBACA,QAIA,oHAEA,iBAIA,gDAEA,oBAEA,MACA,yCAEA,8BAEA,aASA,qBACA,IACA,0BAGA,mBACA,0BACA,kBAEA,0CACA,IASA,8BACA,SACA,OAGA,SADA,UAYA,cACA,qBACA,aAQA,uBACA,QACA,4GAAM,cAKN,2CACA,mBACA,ECjkBA,SACA,cACA,yBACA,MAGA,iBADA,cAUA,2BAKA,WAIA,EACA,UAEA,UAAgB,EAA0B,KAC1C,QAaA,SAqCA,YAWA,SInGA,QAOA,iBAMA,sBAQA,UAQA,wCAQA,4BAQA,yBAQA,UAQA,+BAQA,UAQA,0CACA,IAcA,gBACA,IACA,4CACA,0BAEG,WAGH,uBACA,gBAGA,UACA,uCACI,eACJ,mCAOA,yBAEA,0EACA,CA0BA,SACA,IAKA,6BACA,mCAIA,2BACA,qBAGA,gCACA,mDAGA,6CAGA,6BACA,iFACA,4BAA6B,CAI7B,6CACA,sBAGA,oCACA,sCAAmC,CASnC,8BACA,2BACA,gCAEA,sCAEA,UAKA,0CAFA,OAIA,yBAGA,UACA,wBAEA,gCACA,8BACA,4BACA,OAcA,wBACA,gCACA,aAEA,0BACA,UAGG,mBADH,WAEA,WAEA,mBAOA,aANA,sBAEA,KAGA,WAEA,CAeA,2BACA,wBAEA,sCACA,0DAIA,SAUA,6BACA,kDACA,YAYA,gCACA,uCAEA,wEAKA,OAOA,sBACA,cAGA,kBAOA,mBAGA,mEACA,mBAEA,6BAGA,8BACA,IAQA,gCACA,kDACA,YAGA,gCACA,uBACA,WAGA,4CACA,MAGA,kBACA,WAKA,aACA,MAIA,kBACA,kBAGA,mBACA,eAEA,kCAKA,qBAWA,iBACA,2BACA,8DAEA,mBACA,aAEA,eAEA,wDACA,UAGA,MACA,SAEA,OAQA,gBACA,2BACA,sDACA,UAGA,4BACA,2BAIA,0BACA,UACA,mBAGA,kBAWA,qBACA,gBAiDA,IACA,MAGA,+BACA,qBAGA,YACA,qBAMA,YACA,cAhEA,iBAEA,gBAMA,gBACA,kBACA,yBACA,gDAAqG,CAKrG,gBACA,uCAGA,gBAEA,gBACA,aAEA,cACA,QACA,qBACA,MACI,KACJ,oBACA,SAEA,OAOA,aACA,UACA,8BAIA,oBAyBA,mBAEA,IACA,8BAMA,YALA,gCAEA,6EAMA,sBAKA,8BACA,YAEA,8BACA,4BAEA,wBAQA,wBACA,WAGA,mBACA,uEACA,mDACA,+CACA,0CACA,oEAIA,uCACA,kCAIA,oEACA,+CAGA,iBACA,iBAEA,4BACA,wCACA,2BAGA,kFACA,UAQA,uBACA,qCAGA,uBASA,wFACA,6DAEA,6BACA,4BACA,QASA,4BACA,uBAEA,yBAGA,sCAEA,+CAKA,0DAOA,kBAOA,sBACA,kCACA,WAEA,+BACA,WACA,kCAEA,gBACA,uBAEA,iBACA,CACA,CAOA,uBACA,cAGA,6BAEA,QAOA,eACA,mBACA,wBAGA,qCAEA,QACA,CACA,EAQa,gBC7qBG,QCXhB,UGqBA,QAOA,aAA0B,KAkB1B,oBAOA,qBAOA,yBAQA,kFAQA,mCAQA,uCACA,QAUA,uBACA,qCACA,uBASA,uBACA,mCACA,MAUA,kBACA,wBACA,gCACA,QAQA,oBACA,gCAEA,YACA,wBACA,iCAGA,sCACA,iBAEA,mBACA,CAUA,2BACA,wBACA,gCACA,QAcA,eAA+C,KAC/C,iBACA,cAEA,qCACA,iBAAG,KACH,SACA,4BAGA,mBAEA,WAEA,wBAEA,2BACA,WAEI,wCAEJ,aASA,WAPA,YACA,WAGA,wCAKA,QACA,WAIA,mCACA,sCAIA,+CACA,iCACA,2BAIA,eACA,QACA,CAYA,wBAA4D,KAC5D,8BACA,wBAEA,mBACA,cACA,mBAGA,2BAEA,iBAGA,IACA,mBAEA,eASA,kBACA,kCACA,kCAEA,gBACA,cAIA,6BAHA,4BAEA,SAcA,qBACA,WAEA,uBACA,cAEA,+BAEA,SAGA,cAEA,aACA,SAGA,OAAW,UACX,SAAG,KAEH,SAEA,kBACA,WAEA,gBAEA,SAGA,qBACA,EAAI,KACJ,WAEA,qBACA,aACA,gDAEA,YAEA,SAGA,UACA,eACA,WAIA,oBACA,YAAY,UAGZ,6BAEA,QAAW,UACX,SACA,CAgBA,aAAiC,KACjC,cACA,mBAIA,6CAEA,mBACA,KAGA,iBACA,cACA,YACI,UACJ,cAEA,6CACA,SACG,eACH,mBACG,UACH,SACA,4BAGA,mBAEA,WAEA,wBAEA,SACA,WAEI,+BAEJ,gDACA,gBAEA,YACA,WAIA,4BAEA,8BAAmC,EAAQ,KAC3C,kCAEA,MAEA,+BACA,iCACA,yBAIA,kBACA,QACA,CAWA,sBAA8C,KAC9C,WAAkB,iBAAkC,WACpD,WACA,qBAEA,eACA,WAEA,QACA,CASA,sBAGA,qBACA,uBAGA,oBACA,gBAGA,yBAEA,uBACA,KAEA,QAEA,SACA,cAEA,oCAAkB,MAA6B,eAE/C,WACA,qBAGA,uBAEA,aAEA,CACA,QASA,kBACA,mDACA,uDAEA,iBACA,MAGA,YACA,IAiBA,uBACA,cACA,wDAIA,oBAEA,2BACA,uBAGA,kCACA,IACA,iDAGA,oBACA,gCAGA,eAIA,QACA,YAGA,KACA,aANA,IASA,UACA,cAEA,gBACA,qBAEA,EAAI,KACJ,wBACA,UACA,eACA,kCAGA,wBACA,sCAEA,EAEA,OAEA,KAaA,gBACA,2DACA,MAsBA,6BACA,IACA,YAIA,mBAEA,sBACA,KAGA,mBAGA,qBACA,UAEA,mBAGA,mBAEA,qBACA,WAGA,kBACA,mBAEA,YAEA,IACA,CAEA,KACA,6BAEA,iBACA,oBAGA,SAGA,mBAEA,IACA,CAEA,OACA,KAYA,gBACA,+BACA,MAiBA,4BACA,WAGA,+BACA,qCAIA,8CACA,+CAGA,GACA,IAOA,SACA,cAEA,wDAEA,MAAU,WAAmB,cAC7B,OAIA,eACA,MAAW,cAEX,sBACA,MAEA,KAMA,kBACA,cAEA,UACA,eACA,WAIA,aACA,aACA,CAQA,UACA,4BACA,SAQA,aACA,4BACA,YAQA,sBACA,4BACA,sBAQA,aACA,4BACA,YAQA,0BACA,MACA,YAKA,0BAEA,wCACA,qCAEA,uBAEA,UAGA,SADA,UAUA,sBACA,SAGA,YAEA,gBACA,WACA,+BAEA,kBACA,aAEA,QAEA,OACA,KAYA,yBACA,2DACA,iEACA,YAUA,oCAEA,2BAEA,KAGA,oCAEA,eAGA,sBAIA,+BAKA,kBAmBA,4BACA,SAIA,+DACA,OAKA,6BACA,cACA,yCAEA,0BACA,wBAEA,GAGA,8BACA,cAGA,4DAEA,OAEA,kBAA4B,QAC5B,QASA,sBACA,2DACA,OAGA,sBAEA,kCACA,yBAeA,2BACA,OAEA,mBACA,aAOA,qBAAqC,iBAErC,kBACA,qCAIA,8BAkCA,0DAjCA,wBAKA,0BAQA,4BAKA,0DACA,6BAOA,SACA,qDAKA,SAWA,8BACA,gBACA,sCACA,sCAGA,sBACA,sBAGA,0BACI,mBAEJ,iBAIA,WACA,KAWA,6BACA,OACA,iBAGA,2BACA,mBACA,8DAEA,aAEA,sBAEA,mBACA,SAKA,QACA,GACA,cACA,6BAGA,iBAEA,QAEA,OACA,KASqB,EC5jCrB,gBASA,YACA,mBAOA,eACA,CAQA,uBACA,MAKA,aAEA,gDAIA,gCAFA,KAIA,eACA,aACA,qBAEA,gBACA,MACA,uByWvCA,EACA,QAMA,eAOA,MAQA,gBACA,YAYA,SACA,MACA,YAQA,UACA,MACA,YAKA,UACA,MACA,eACA,eASA,EChDA,YCHA,IDIA,eACA,GACA,sCACA,2CACA,EAEA,ECTA,mBACA,eACA,CAQA,sBACA,CACA,aACA,iBACA,yBAQA,gCAOA,6BAQA,cAQA,0FACA,MAMA,QACA,0CACA,cAKA,WACA,mBAEA,aACA,iDAEA,QAKA,SACA,OAEA,6BACA,mDAEA,QAKA,UACA,OAEA,iCACA,YAKA,UACA,OAEA,iCACA,YAQA,gBAEA,gBAuHA,WAKA,iBAIA,2BACA,oBAKA,IACA,IAtIA,aAGA,oBAGA,kBACA,UAIA,cACA,gCACA,0BAGA,mBACA,aAGA,kBACA,yBAEA,MAIA,kBACA,0BAGA,qBAIA,wCACA,uCAEA,oBAGA,gBACA,MACA,iBACA,kBACA,QAMA,kBACA,uCAEA,YACA,CAMA,MAEA,uBACA,2CACA,QAGA,yBACA,WACA,+BACA,8BAIA,sBACA,qCAEA,qBACA,MACA,WACA,cACA,cAGA,SAIA,mCAEA,qBAEA,wBAMA,4CACA,kDAGA,aACA,SACA,SACA,oBAEA,eAEA,oBAIA,+BAEA,QA6BA,sBACA,OAGA,6DACA,uEACA,CAIA,qCACA,KCrRA,EACA,YAEA,ICdA,MCsBA,GDkCA,eACA,cAuBA,IACA,KAEA,IAIA,SAHA,SACA,QACA,YAGA,cAEA,OAEA,OAEA,kBACA,MAEA,cACA,OACA,MACA,MAEA,kBACA,MAEA,cACA,OACA,MAKA,cACA,cACA,IAEA,aACA,OACA,WACA,MAGA,yBACA,MAEA,cACA,QACA,gBAIA,SACA,MAEA,QAEA,WAEA,aAaA,OACA,OAEA,UACA,YACA,KAEA,MACA,IACA,iBAEA,MAEA,WACA,mBACA,gBAEA,IACA,CAIA,MAHA,gBAEA,kBAEA,OAhHA,IACA,EACA,KACA,KAEA,KAVA,EACA,EACA,EACA,EACA,KAOA,8BAEA,WAhBA,uBA2HA,gBA1GA,EACA,cACA,UACA,oCACA,4BAGA,cAiGA,iBApCA,CACA,YAEA,oBACA,MACA,QAEA,IA8BA,gBA7BA,uBACA,KAEA,GA6BA,EC7JA,mBACA,eACA,CAWA,iCAQA,qBAQA,4BAUA,8BASA,gCASA,oGAEA,0DAQA,gDACA,CAKA,WACA,WAGA,8BAIA,+CACA,MACA,yBAEA,mBACA,OAKA,UACA,OAEA,6BACA,mEACA,QAUA,0BAIA,4DAKA,mCAIA,8BACA,mCAEA,wEAOA,8BASA,2BAKA,oBAHA,mHAMA,2BACG,aACH,SACA,mBACA,UACA,eAIA,mCAMA,0BACA,oCACA,GAOA,qBACA,uBACA,CCzLA,EACA,QAMA,mBAOA,MAQA,gBAQA,4BAEA,UACA,OAQA,aACA,qDACA,UAKA,iBACA,eACA,gBAKA,kBACA,eACA,iBCrCA,EACA,mBAqBA,eACA,CAQA,cACA,aAKA,WACA,qEAEA,4BACA,0BACA,MACA,gBAEA,aAAI,EAAG,iBACP,YACA,EAWA,YACA,MACA,4CAEA,cC3EA,EACA,mBACA,eACA,CAEA,cACA,mCAEA,+BACA,GAMA,6DACA,EAEA,sBACA,qBAEA,iCACA,YAGA,eAEA,SAQA,EAEA,cACA,aACA,OAKA,UACA,MACA,oCAGA,wBACA,SCtDA,EACA,mBACA,eACA,CAEA,cACA,gCAEA,cACA,oBACA,WAEA,iBACA,4BACA,mBAEA,wBACA,WACA,KAEA,GA6CA,EjX5DA,mBAMA,eACA,CASA,oGACA,IAKA,UACA,cAEA,+BACA,WAEA,wCAEA,cAEA,6CAEA,SAAG,EAAG,UACN,UAKA,UACA,OAEA,iDACA,QAeA,wBACA,uBACA,eACA,yBAGA,oCACA,YAIA,2CACA,cAGA,wBACA,CACA,eACA,4BAIA,yBAMA,0BACA,oCAOa,KIvGb,IDMA,WACA,oCACA,KAEA,EELA,QA4BA,eACA,SASA,8CAEA,SACA,WACA,YAGA,yBACA,aAEA,uDAaA,gBACA,KACA,4FAAM,CAKN,4CAEA,cAEA,wBAAG,eACH,MAAU,cAEV,yBACA,KACA,EACA,QACA,cACA,EACA,QAEA,UACA,SA4CA,OAOA,QACA,eACA,KASA,YACA,aACA,wBACA,yBACA,YAEA,OACA,IASA,YACA,aACA,YACA,cACA,aAEA,UACA,IAQA,mBACA,SACA,mBACA,2BACA,+BACA,4BAGA,gCACA,yBAEA,eACA,WAEA,KAEA,SAQA,uBACA,cAGA,8BAEA,UAEA,CAOA,UACA,wBACA,MAYA,aACA,cACA,mBAGA,YACA,gCAGA,mCACA,SACA,cAEA,mBACA,mBAEA,YAIA,gBAGA,UACA,UAGA,CACA,QAUA,WACA,UACA,sBACA,KAIA,SACA,QAQA,YACA,cAEA,iCACA,WAUA,8BACA,cACA,cAEA,KACA,gDACA,uDACG,iBACH,iBAEA,2BACA,+BAEA,kCACA,IAGA,aACA,cAEA,cACA,eAEA,UACA,IAQA,2BACA,MAEA,qBAEA,uBACA,gBACA,eAMA,eACA,iCACA,mCACA,aAEA,IACA,OAEA,CACA,QACA,EAEA,KAMwD,qDChSxD,iBACA,CACA,8BA2CkB,4BAvDlB,WACA,SAEA,WACA,IAEA,UAGA,IChDA,QAIA,cAOA,kBAQA,oBAUA,yBAQA,qBAUA,cAYA,0BAQA,4DACA,8CAQA,yBAGA,UACA,qBACA,qBACA,qBACA,qBAEA,mBACA,SAEA,oBACA,SAeA,eACA,uBAEA,OACA,KAGA,iBAEA,sBAEA,+BACA,WAGA,aAGA,SADA,UASA,eACA,wBACA,MAyBA,uBACA,gCAEA,mBACA,iBAcA,kBAZA,gBAGA,gEACA,wEACA,oEAEA,6BACA,mBAGA,oBAcA,0BACA,cAEA,yBAEA,2BAEA,2CACA,+CAEA,8CACA,WAEA,YASA,kBACA,mBACA,MAQA,qBACA,sBACA,MAQA,SACA,MACA,iCACA,cACA,iBAMA,QACA,oBACA,wBAGA,qCACA,cASA,kBAEA,2EACA,CAMA,uBACA,wBAGA,sBACA,0BACA,iCAGA,IAKA,mBACA,gCACA,WAEA,SAKA,kBACA,gCACA,WAEA,QAKA,UACA,gCACA,WAEA,SACA,EC9TA,SEOA,QAMA,eAOA,MAQA,kBAQA,mBAiBA,0CACA,aACA,+BAIA,uDACA,kBACA,kBAAG,EAAG,UAGN,mDACA,oBAEA,2BACA,8BACA,QAAG,EAAG,UAGN,sDACA,qDACA,WAEA,oDACA,wDACA,WAGA,gEAGA,iDAAsD,UACtD,6CAA4C,UAG5C,6CAAwD,UACxD,6CAA2D,UAC3D,6CAA8D,UAC9D,6CAAkE,UAClE,OAoBA,uBACA,mBACA,6BAEA,WAGA,mBADA,mBAOA,UACA,WACA,eACA,eACA,EC5IA,SEOA,mBAQA,iBACA,CAQA,cAGA,mCACA,kDAQA,6BAaA,4CAEA,WACA,eAKA,UACA,gBACA,mCACA,iCACA,sBACA,UAOA,WACA,WACA,MAKA,UACA,kBACA,KAKA,sBACA,sBACA,UAKA,4BACA,sBACA,SAQA,gBACA,cAGA,2DACA,IACA,aACA,gBAIA,2BACA,cAEA,oBACA,CACA,MACA,QAIA,sBAIA,kCACA,uBAGA,kBAEA,SACA,EACA,CAWA,mBACA,yBACA,YAEA,WACA,IACA,uBACA,QACA,oBACA,QACA,QAEA,OACA,EqW7JA,EACA,QAOA,WACA,oDACA,sBACA,gBAEA,iBACA,SCVA,EACA,QAIA,cAOA,oBAQA,qCAA0C,CAQ1C,kCACA,MASA,UAEA,wCAGA,kCACA,UAQA,UAEA,cAGA,oCACA,YAUA,UACA,2CACA,iBACA,kCAEA,gBACA,4BAGA,IACA,QCjFA,EACA,QAIA,eAOA,MACA,QAKA,UACA,MACA,eACA,ECbA,SACA,QAOA,aAA0B,KAO1B,MAQA,2BAQA,oCAYA,0CAYA,8CASA,QAOA,aACA,oBACA,MAOA,YACA,wBACA,IAOA,WACA,oCACA,IAaA,SACA,IACA,gBAEA,sBACA,MAEA,KAMA,gCAGA,qCAMA,oBAEA,qCACA,aAIA,OACA,yBACG,qCAMH,iBAGA,iEAEA,mBAEA,mBAEA,WACA,IAQA,OACA,IAEA,MACA,mCACG,eACH,0BAOA,4BAGA,oEACA,IASA,YACA,IAEA,YACA,iCAKA,qBACA,UASA,UACA,IAEA,UADA,eAGA,YA6BA,GA5BA,oBACA,oBACA,SAGA,qBAEG,aACH,oBACA,WACA,YAGA,SAGA,QACA,MACA,mBACA,mCAGA,uBASA,+DACA,iBAEA,oDACA,OAMA,yCALA,4CAEA,oBAEA,aAYA,SACA,oBACA,QAWA,UACA,oBACA,SAWA,YACA,oBACA,WAMA,QACA,UACA,4CACA,0CAGA,WACA,oBAEA,EAiFA,UACA,SAMA,+BAGA,yFAEA,oBAOA,SACA,+BACA,SAUA,aACA,CACA,mDAEA,oCAEA,KAEA,EAQA,uBACA,cAKA,6BACA,8BACA,sCAMA,UACA,uCACA,2CACI,aACJ,SAEA,uCACA,2CAEA,cACA,QACA,CAGA,WACA,UAIA,wBAGA,yCACA,2CAGA,eAEA,SACA,EAKA,oBACA,2BACA,WAeA,EAEA,SvW1dA,mBAMA,eACA,OAGA,YAIA,mCACA,GACA,cAGA,yBACA,+EAEA,YAGA,2BACA,iBACA,0BAEA,QAQA,QAQA,6BACA,IAMA,UACA,iBACA,UASA,aACA,MACA,gBAmCA,eACA,gBAMA,mBAGA,mFASA,SAEA,eACA,eACA,sBAKA,2BACA,UACA,sBAEA,KAGA,2BACA,UACA,UAEA,mBACA,EAEA,EAaA,EAQa,YEjMb,IDSA,aACA,OACA,cAEA,ECyBA,QAMA,eACA,uBAUA,aAiDA,gCACA,IAWA,SACA,0BACA,CAGA,kBAGA,YADA,gBAsCA,SACA,CASA,wBAPA,sBACA,CACA,OACA,8BAGA,eASA,UACA,UAMA,yBAGA,uIACA,YA8BA,YACA,cACA,MACA,0BACA,SACA,MACM,QACN,cAIA,KAEA,SACA,KAuCA,iBACA,OACA,QACA,eACA,CACA,sBACA,mCAEA,YAEA,WACA,eACA,kDAEA,YAEA,EA0DA,mBACA,GAQA,qBAGA,oGACA,OAQA,eACA,IAEA,GAeA,OAbA,oBAGA,8BAGA,YAQA,QAIA,qHACA,UAEA,oBAEA,iBAQA,kBACA,SAGA,KAQA,sDA3XA,oCAsXA,WACA,0BACA,+BAEA,oBASA,eACA,SAIA,KAiCA,6BA/BA,6CAaA,YACA,6BACA,aACA,aACA,MAUA,sCAGA,KASA,qBACA,WAEA,UAIA,sBACA,SAEA,yBAEA,kBAGA,uBAIA,oBAUA,6CAmBA,WAQA,gBAIA,WACA,SAGA,kCACA,CACA,iBACA,UAEA,QASA,iBACA,mDAmBA,aACA,SAGA,aAUA,eAEA,4BAEA,wBAEA,IACA,SAIA,uBA6BA,2BACA,WAEA,sBACA,SAQA,KACA,6BACA,QACA,YACA,QAWA,WAEA,UACA,CAQA,0BACA,WACA,+BACA,+BACA,iBAEA,sBACA,YACA,aACA,GAGA,sBACA,wBAEA,QACI,UAEJ,aACA,cAGA,yBAEI,kBACJ,QAEA,yBACA,WACA,aAEA,gBAEA,sBACA,mBACA,KACA,cAEA,cACA,sBAKA,YACA,gBAEA,cASA,mBACA,SAIA,kDACA,yCACA,oBAEA,cACA,+BAEA,KACA,kCAEA,OACA,CAeA,mBAAqB,oBAAwB,QAC7C,WAGA,WAEA,kBAEA,eAEA,qBAIA,uBAGA,gDAEA,OAWA,6BACA,kBAWA,kBACA,QAIA,SACA,KAKA,4BAHA,kCAIA,WAGA,cACA,WAEA,qBAEA,iBAEA,WAAkB,eAAgC,OAClD,mDAEA,YACA,EAQA,SACA,QAMA,eACA,eA+BA,OAWA,YACA,8BAEA,qCACA,eAYA,iCACA,aAEA,sEAGA,iBACA,2DACA,YACA,CAYA,EACA,mBAUA,gCACA,gBACA,eACA,cACA,iDAEA,iDAGA,uBAEA,iCAGA,cACA,8BACA,SACA,CAQA,EACA,mBAIA,YACA,eAEA,gCACA,gBAca,EC34Bb,QAQA,eAgCA,cAQA,UAUA,mBAWA,qBAQA,wBASA,kCAGA,yDACA,GACA,QAgBA,EA6CA,mBACA,aACA,mBAGA,8CACA,KAmCA,mBACA,SAEA,OAGA,6BADA,QA8DA,oBACA,CACA,SAGA,cACA,8BAEA,MAUA,sBACA,CACA,SAGA,cACA,8BAEA,SAWA,eACA,eACA,SAeA,kBACA,gBACA,WA2DA,SACA,SAMA,wBAIA,8EACA,sCAGA,6CAGA,kBACA,aAUA,UACA,MAEA,iDACA,UACA,EAEA,SC9dA,SGAA,SDAA,WASA,YACA,GCZA,EAGA,qBAwCA,KACA,mBAIA,eACA,CAEA,sBASA,4BASA,mBAiBA,uBASA,qBAUA,yBAQA,yBAgBA,+BAEA,oCACA,KACA,iBACA,OACA,CACA,wCAAuD,qBACvD,qBACA,6CACA,oCAGA,oBACA,UACA,oBAIA,2BAEA,SAOA,OACA,MACA,YAOA,OACA,MACA,YAiCA,YACA,MAEA,kBACA,0BAA2C,UAC3C,cACA,kBACA,GACA,sBACA,sBACA,sBAEA,qBACA,WAGA,qBAAS,cAA4B,QAErC,yBAAwB,cACxB,YAmCA,OACA,MAEA,2CACA,MACA,eAEA,sBAEA,cAEA,OAKA,4DACA,0BAKA,QACA,MAEA,iCAIA,+DAEA,0DAEA,UAEA,OASA,iBACA,MAEA,yBACA,yBAGA,sDACA,WAGA,cAGA,mBAIA,uBACA,UAEA,WAAG,EAAG,CAGN,qDACA,MACA,WACA,EAOA,eACA,gCACA,uCACA,SAQa,EAiCb,yBAkBA,GACA,uBA4KA,GACA,oBAGA,yBACA,KACA,sCACA,OAGA,wCACA,KACA,yCACA,2BAGA,yCACA,KACA,iCACA,2BAKA,yCACA,KACA,4BACA,OAGA,4CACA,KACA,uBACA,2BAGA,6CACA,KACA,+BACA,2BAKA,yCACA,KACA,6BACA,OAGA,4CACA,KACA,gCACA,2BAGA,6CACA,KACA,wBACA,2BAKA,qCACA,KACA,sCACA,OAGA,wCACA,KACA,yCACA,2BAGA,yCACA,KACA,iCACA,2BAKA,yCACA,KACA,4BACA,OAGA,4CACA,KACA,uBACA,2BAGA,6CACA,KACA,+BACA,2BAKA,yCACA,KACA,6BACA,OAGA,4CACA,KACA,gCACA,2BAGA,6CACA,KACA,wBACA,2BASa,cExqBb,mBAIA,wBACA,OACA,mBAKA,OAOA,WAaA,gCACA,6BACA,mBAGA,uDAGA,MACA,IASA,iBAGA,uCAGA,gDACA,QAQA,kBACA,+CAEA,oBACA,IAQA,WACA,oBACA,MAUA,OACA,mBAMA,mBAIA,2FAEA,2CAIA,+BAGA,aACA,QASA,UACA,UAMA,wBAIA,sHAEA,mBAGA,sBAGA,mDAKA,aAGA,mBAEA,MAEA,kBAEA,SAQA,kBAEA,uCAGA,+BACA,sBAWA,OAAS,2BAA8B,IACvC,WAEA,8BACA,0BACA,sBASA,sBACA,gCAGA,SAQA,aANA,mBAA+B,YAC/B,cAIA,oB+V3MA,EACA,QACA,cAQA,UAQA,oCAQA,uBAQA,gCACA,IAOA,OACA,mBACA,oBAGA,qFAAkE,CAClE,wDAAuD,CACvD,+BACA,MAOA,UACA,UACA,qBAGA,wBACA,cACA,gCAEA,UAQA,UACA,mBAEA,4BACA,sBACA,YASA,QACA,mBAEA,iEACA,qBACA,UACA,YAAG,EACH,EASA,EAEA,SACA,S9VhFA,QAUA,eACA,kBA2CA,qBACA,0CACA,SAEA,WACA,uBAGA,cACA,wCACA,CACA,UACA,GAEA,EAEA,CASA,YACA,kCACA,IASA,WACA,iDACA,IASA,WACA,+BACA,EASA,eACA,gCACA,EASA,cACA,OAGA,WACA,yCAGA,kCACA,uCAGA,eAIA,WADA,MAIA,KAKA,aACA,kBACA,MAKA,YACA,kBACA,KAKA,YACA,kBACA,KAKA,gBACA,kBACA,SAQA,UAEA,MAEA,OAWA,qBAEA,cACA,0BAEA,UACA,SAKA,SACA,mCAIA,eAEA,WACA,yBAGA,UACA,MAIA,YACA,QAAG,OAEH,aACA,KAOa,EC9Qb,mBAIA,eACA,CAEA,0BACA,KACA,kBACA,CAKA,kCCDA,ECRA,mBAIA,eACA,CAQA,yBAQA,qCAQA,uBASA,gCACA,iBACA,wBACA,mCACA,mBAEA,CAGA,sCAIA,yDACA,KACA,iBACA,CAKA,oCAEA,SAEA,cAGA,QAKA,SACA,OAGA,6BACA,8BAGA,oCACA,yBACA,QAEA,iCACA,4BACA,QAGA,iCACA,QAKA,QACA,mBACA,YASA,oBACA,YACA,CACA,sBACI,UACJ,wBAmBA,cACA,KACA,2EAAM,CAGN,QACA,EChIA,ECLA,mBAIA,wBACA,OACA,mBAKA,sBACA,OACA,IAKA,OACA,cAOA,iCAEA,wCACA,YACA,CAOA,sEAQA,iCAWA,yFAGA,UACA,8BAIA,mCACA,OAQA,YACA,mCACA,uCAEA,mDACA,QAOA,qBACA,cAGA,mEACA,kCACA,qBAEA,MACA,EAWA,yBACA,8BACA,gCAEA,2CAEA,oBAEA,mBAIA,YACA,+BAGA,sDAEA,2BACA,kBAEA,MACA,EAOA,OAEA,4BAMA,qFAMA,iEACA,mCACA,0BAGA,qBACA,WACA,0BACA,2CAEA,qDAKA,OACA,4BACA,2DACA,oCAEA,aASA,0BACA,cACA,mBAGA,mBAEA,iBAKA,YACA,qBACA,qDAIA,8BAKA,gBACA,2BAGA,iBAEA,GACA,YAEA,MAKA,UACA,oCACA,cACA,sBACA,SAqBa,ECtOb,QAOA,eAOA,MAQA,6BACA,IAOA,SACA,wBACA,MAWA,SACA,SAOA,YACA,0FAAwF,CAIxF,8BACA,QAYA,UACA,UASA,YACA,kGAAgG,CAIhG,wDACA,OAQA,OACA,6BACA,MAQa,EEtHb,QAOA,iBAIA,MAKA,cAKA,6BAKA,4BACA,MAKA,OACA,cACA,cACA,qBAEA,uBAGA,wCACA,+CAIA,2CACA,gCAEA,iCAEA,oBACA,kBACA,6BACA,sCACA,qBACA,yBACA,GACA,MACA,aACA,GACA,MAEA,GAKA,UACA,WACA,SuVrEA,EACA,mBAMA,eACA,CASA,wBAQA,kBAKA,SACA,OAEA,cACA,uBAKA,UACA,sCAEA,eACA,SAOA,wBACA,8CACA,KACA,iBACA,CAMA,qEACG,OAEH,uBACA,cCnEA,EACA,mBAQA,iBACA,CAEA,sBAGA,mCAGA,oCACA,KACA,iBACA,OACA,sCACA,cACA,sBAEA,6DAUA,gBAQA,0BAQA,qBAQA,iBAMA,SACA,OAEA,cACA,sDAEA,2CAEA,OAKA,UACA,MACA,2CAGA,uBACA,SCxFA,EACA,mBASA,iBACA,CACA,wBACA,oBAOA,kBACA,0BAIA,YACA,MACA,4BACA,OANA,8BAEA,YAOA,+BC3BA,EACA,mBAMA,iBACA,CAQA,uBAEA,uCACA,SAKA,sBACA,sBACA,OACA,mBCFA,MACA,mBAYA,iBACA,CAEA,sCACA,gEAEA,0BACA,iCACA,uCACA,UASA,UAGA,cAEA,yBAEA,gBACA,2BACA,WA0CA,mBACA,yBACA,YAEA,WACA,IACA,uBACA,MACA,cACA,UACA,cACA,sCACA,QACA,oBACA,QACA,QAEA,OACA,EACA,E1VlIA,QACA,eAOA,YAQA,WACA,SAOA,YACA,qBACA,KAUA,WACA,qBACA,UAQA,aACA,cACA,YACA,ECzCA,mBACA,eACA,gBAQA,GAEA,0EAEA,qCACA,gBACA,aAEA,gBACA,CAfA,cAEA,gFAA6C,UAC7C,iCAA4C,UAE5C,OAYA,cACA,SACA,uDAGA,eACA,qCAGA,yBACA,SACA,EGxCA,KAOA,wBCwFA,mBAIA,wBACA,OACA,WAKA,OACA,gBA6DA,WACA,yDAEA,cAEA,0CAAyC,mCACzC,MAEA,cApEA,WACA,qBAQA,6BAEA,SAIA,wDAGA,MACA,WAGA,iBACA,mBAEA,aACA,4BACI,wBACJ,+BAGA,0CAEA,0CAAsC,CAEtC,cACA,sBAAG,EAAG,UAEN,wDACA,uBACA,qBAKA,2BAEA,uBACA,gBAGA,4BACA,qBACA,UACA,EACA,CAAG,EAAG,UAIN,iCASkD,UAClD,qCAGA,GACA,aAEA,iBAEA,MAAG,EAAG,UAEN,iDACA,WACA,8EACA,mDAGA,WACA,sCACA,oCACA,QAEA,EAAG,EAAG,UACN,OsV1LA,EACA,QAMA,eAOA,aAqDA,MACA,YACA,MAzCA,kBAUA,yBAEA,8BAGA,gEACA,MACA,SAEA,0BACA,MACA,aAEA,MAAG,EAAG,UAGN,sDAIA,iCAAgD,UAChD,gBAEA,wBACA,2BAEA,UAEA,EAYA,UACA,MACA,YAaA,WAKA,UACA,MACA,eAaA,EAEA,SrV3HA,mBAIA,UACA,qBACA,aAEA,6BACA,qCAEA,iCAA+B,CAC/B,SACA,EAQ6C,ECpB7C,mBACA,eACA,CAEA,+BACA,+BACA,iCAEA,UACA,EAKA,WqVfA,EACA,mBAIA,wBACA,OACA,OAEA,OACA,cACA,mBAEA,OAEA,uCAGA,0CACA,WACA,WACA,mBACA,sBAAG,EAAG,UACN,OACA,EnVZA,QAOA,oBAOA,MASA,qBAQA,OAQA,aAEA,4CACA,MACA,WAEA,oCACA,MACA,QAEA,qBAEA,oDAEA,iEAsBA,yBAQA,YACA,aACA,mCAGA,cACA,MAQA,SACA,MAEA,wBACA,YAEA,UAKA,OACA,MACA,WAKA,SACA,MACA,WAKA,UACA,iCACA,iEACA,8EACA,yBAaA,YAEA,yCACA,+BAEA,UAQA,UACA,QACA,2BACA,eAEA,EoV1KA,EACA,mBAQA,iBACA,CASA,+BACA,WAOA,aACA,aACA,OAKA,UACA,OAEA,uBACA,SAgBA,SAAsB,KACtB,qBACA,mBACA,OACA,8BACA,oBAEA,iCACA,WAEA,yBAGA,6BAIA,6CAIA,sDAGA,gEAGA,8BAEA,sBACA,QACA,EACA,EnV9EA,mBAIA,wBACA,OACA,OAKA,OACA,cACA,mBACA,iDAIA,mBAEA,4CACA,MACA,mBAAG,EAAG,UAEN,gDACA,MACA,qBACA,EAkBA,oBACA,qBACA,aAOA,UAIA,8BAIA,gBAEA,4BACA,8CACA,MAEA,KACA,SAUA,sBACA,qBACA,WAOA,EACA,QAMA,eAOA,MAQA,kCACA,OASA,YACA,IACA,WAEA,qDAEA,aACA,8BAGA,2BAoBA,uCAEA,SAGA,SACA,GAGA,wCAGA,iBAEA,mBACA,GAKA,eACA,2DAGA,gCAGA,iCACA,8BAGA,2BACA,MAKA,6DACA,+BAGA,OACA,MAGA,eAEA,QAAS,8BAAuC,aAGhD,YAGA,8CAGA,4BACA,iBAIA,kCAGA,iCACA,CACA,OACA,QAEA,eAEA,yBACA,IACA,eAYA,2CAEA,mCAEA,OAEA,QAAS,8BAAuC,aAGhD,YAGA,8CAIA,mCACA,8BACA,wBACA,oCAEA,wCACA,CACA,OACA,QAEA,eAEA,4BACA,IAIA,4BACA,wBACA,6BACA,iCAEA,iCAKA,0BACA,WAEA,YACA,EAEA,SACA,IACA,cACA,iBACA,gBACA,aACA,EACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GAGA,KACA,UAAqB,IAAa,OAClC,OASa,QC1Tb,mBAQA,iBACA,CASA,cASA,wDACA,mBAYA,SAAsB,KACtB,qBACA,uBAEA,0BACA,cAEA,wCAOA,eAGA,iBACA,iCAAgD,iCAIhD,oEACA,GAMA,iBAJA,0CAKA,YAGA,aAEA,wDACA,IACA,eAAuB,yCAEvB,aAEA,wCAAiE,CACjE,yCAEA,+CAEA,yBACA,QACA,EAoBA,+CAEA,IACA,IAGA,6BACA,aACA,qBAIA,sCAEA,4BACA,GAGA,4BAAgC,2BAChC,OAGA,4BAKA,aAKA,0BAOA,qCACA,qBACA,aACA,qBACA,4BAEA,0CACA,0CAEA,iBACA,iBmVnKA,EACA,mBACA,eACA,CAEA,eAEA,sBACA,sCACA,eAEA,EAEA,yBACA,MAEA,uBACA,mBACA,iBACI,kCACJ,sBACA,kBAEA,gBAGA,iCACA,gBAEA,+BACA,YACA,EAKA,WCpCA,EACA,mBAIA,wBACA,OACA,QAEA,OACA,cACA,mBAEA,OAEA,wDACA,6CAEA,6CACA,2DAA8E,wBAC9E,aACA,mBACA,sBACA,ECvBA,EACA,mBACA,sBACA,OACA,OAKA,wBACA,OACA,QA+BA,EpV1CA,mBACA,eACA,CAWA,cAQA,kCAGA,cACA,SAKA,UACA,gBACA,oBAQA,YACA,8BAEA,YACA,mCACA,6BAGA,6BAAqB,SACrB,mBACA,SAKA,aACA,MACA,eACA,SAUA,yBACA,qBAGA,SAGA,sBACA,SAMA,YACA,0BAKA,gBAEA,OAGA,GACA,oBAEA,cASA,SACA,qBAGA,aACA,6BAEA,wBACA,UAIA,2BAGA,oCAGA,8BACA,qCACA,yBAGA,yBAEA,iBAGA,UAGA,6BACA,aAGA,4BACA,qBACA,CAEA,CACA,QAIA,EClJA,mBAUA,gBAEA,qEAEA,4BAIA,2CACA,sBAEA,wDACA,mEAEA,mCACA,QAEA,QACA,SoV5BA,EACA,mBASA,UACA,qBAIA,8CACA,8CACA,gCACA,sCAEA,mEACA,2BACA,MAEA,QACA,SCzBA,EACA,mBAIA,eACA,CAwBA,gCACA,QAKA,OAEA,+BACA,sCAGA,6CACA,mDAEA,qEAEA,6BAGA,0DAEA,yBACK,+CAGL,2BACA,8BAKA,kCACA,OAAG,EAAG,UAEN,8DACA,mBACA,WACA,ECvEA,EACA,mBAIA,cACA,CAEA,qBAQA,gCAUA,uBAEA,8BACA,KACA,SACA,wCACA,OACA,uBAGA,aAKA,SACA,OAEA,cAIA,sDACA,oBAOA,oBACA,iBACA,YACA,iDACA,iBAEA,sCAEA,GACA,6DAEA,GACA,CCtEA,EACA,mBAIA,eACA,CAQA,yBAqBA,wBAEA,kBAEA,8BACA,KACA,kBACA,OACA,CACA,kCACA,iDAGA,mBACA,CACA,KAEA,kBACA,CAKA,qCACA,CACA,WAMA,aCjDA,EACA,mBAIA,eACA,CAEA,sBASA,sBASA,kBAiBA,sBAYA,sCAQA,qBAWA,mBAUA,oBASA,yBAQA,yBASA,wBAUA,6BAQA,sBAQA,yCAQA,yCAWA,+CACA,QACA,eACA,aACA,wCAUA,wBACA,KAEA,oBACA,OACA,CACA,iDACA,iDACA,+BACA,0BAEA,kDACA,wBAGA,2BAEA,YACA,qBACA,GACA,gBAEA,mBAGA,MACA,oBAIA,aAEA,gBAUA,KAKA,SACA,UAEA,mBACA,uBAEA,iCAEA,sBACA,MAEA,wBACA,oCACA,UAKA,QACA,cACA,OASA,qBACA,SAEA,OAIA,8BAHA,6CAEA,oBASA,mBACA,SAEA,OAeA,qBAdA,KAEA,kBACA,CAGA,qCACA,CACA,2BAKA,cAeA,yBAEA,UAIA,4BAGA,mBACA,UAEA,OAAe,IAAU,KAAkB,MAAY,MAKvD,IACA,EACA,wCCrPA,MACA,mBAIA,sBACA,OACA,IAIA,wBACA,OACA,MAIA,OACA,cACA,WACA,+CACA,gDACA,6BACA,kCACA,wCACA,OAUA,oBACA,cACA,oBACA,wCACA,SACA,UASA,aARA,CACA,QACA,OACA,YAEA,sCACA,6CACA,aAEA,ECrHA,EACA,mBACA,sBACA,OACA,aCnBA,EACA,QACA,cACA,oBAQA,gBASA,4BAEA,qBACA,eACA,MACA,CAOA,YACA,qBACA,KASA,QACA,cACA,4BAEA,wBACA,cACA,KACA,OAEA,gBACA,GACA,QAEA,gBACA,GACA,UAEA,eACA,gBACA,EAKA,QACA,cACA,OACA,ECnDA,SACA,mBAIA,wBACA,OACA,gBAKA,OAMA,cAqBA,2BAaA,0BASA,yEACA,mBAEA,EAUA,aACA,qBACA,aACA,QAIA,eACA,KAUA,gBACA,UA+BA,8BAEA,6DAGA,aACA,UA2BA,uBAzBA,8BAEA,kCACA,OAEA,sBACA,aAGA,cACA,UAEA,iCACA,OAEA,sBACA,UACA,mBAIA,kBACA,aAEA,IASA,iBACA,gCAEA,eAEA,wBACA,SACA,EAOA,SACA,QAOA,iBAOA,SAQA,SAQA,YAQA,wBA2BA,yBASA,4BASA,0BASA,yEACA,mBAUA,6BACA,KAuBA,OACA,IACA,iCAGA,mHAEA,iCACA,WACA,kBAIA,sBACA,IACA,gCACA,UAGA,4BACA,qBACA,KACA,EAsBA,SACA,IACA,iCAGA,uHAEA,0BACA,cACA,WACA,6BAIA,sBACA,IACA,6BAGA,UAEA,kBADA,SAEA,EAKA,QACA,cACA,mBAEA,UACA,2BAGA,sCACA,qBAGA,aACA,UAOA,WACA,MACA,oBACA,qBACA,iBACA,2BACA,WACA,EAqFA,S3VlgBA,SACA,iBACA,MAQA,uCCFA,mBAIA,sBACA,OACA,IAIA,wBACA,OACA,uBAIA,OACA,gCAKA,gGACA,GAOA,EACA,QAQA,mBAMA,MAMA,cAMA,WACA,GAOA,SACA,2BACA,MACA,oBACA,yBACA,cACA,EAOA,QACA,MACA,cAEA,OAMA,eACA,qBACA,mCACA,uBACA,MAQA,oBACA,cACA,WACA,cACA,6BAA4D,eAC5D,mCACA,qCACA,mCACA,WACA,qBACA,gBAEqB,WACrB,4CADA,UAIA,KACA,kDACA,GACA,mCACA,mBAEA,OAEA,EAMA,eAEA,YACA,wCACA,6BAEA,eACA,O2VtIA,EACA,QA+BA,mBACA,IAEA,MACA,qBACG,QAIH,QACA,MAAW,CAGX,uBAA8B,CAC9B,SACA,CAEA,mCACA,IACA,sBAGA,UACA,YAKA,yCAEA,WACA,iBAGA,iBACA,aAGA,qCACA,GAGA,iBAMA,yCAEA,oBAGA,kEAGA,UAEA,YAAe,YACf,SACA,EACA,EACA,E1V9FA,QA8CA,mBACA,IACA,GACA,EACA,EAEA,cACA,QAEA,IAGA,IACA,mBAEA,IAIA,eACA,IACA,QACA,MAEA,UAEA,2BAIA,iBACA,CACA,QACA,IACA,IAIA,uBACA,OAGA,eAEA,OAEA,UACA,cACA,6BAGA,UACA,UAEA,wCAGA,eACA,CACA,SAEA,SAGA,gBACA,UACA,UAEA,oBAEA,qCACA,IACA,sBAGA,UACA,aAGA,0BAEA,gDACA,OAGA,uBACA,+BACA,UACA,KAGA,2BACA,2BAIA,cACA,gCACA,OAEA,IAEA,QAGA,8CACA,2BAIA,cACA,gCACA,OAEA,IAEA,eAIA,sCAEA,oBAEA,4BAGA,oBAGA,wBAGA,mBACA,UAIA,YAEA,QACA,EACA,EAOa,ECtMb,mBAIA,wBACA,OACA,YAKA,YACA,MACA,2BACA,kCACA,8BACA,2BAWA,sBACA,qBAEA,eAEA,+CAGA,sBAEA,oDAEA,eAeA,6BACA,qBAEA,eAEA,qDACA,+CAIA,eAKA,8DACA,yDAIA,iBAEA,8CAGA,OAaA,yBACA,iCACA,6BACA,gCACA,WACA,gBAAuC,QAGvC,oCACA,MAAY,CAEZ,iCAAwC,CACxC,SACA,EACA,EAUA,4BACA,0BAEA,0CAEA,aCjDA,EACA,QAIA,cAOA,MAQA,2BACA,IASA,UACA,aAEA,eACA,IASA,eACA,mBACA,MACA,UACA,gBAGA,MACA,IASA,iBACA,mBACA,MACA,YACA,eAGA,MACA,IASA,cACA,mBACA,MACA,SACA,gBAGA,MACA,IAmBA,gBACA,mBAEA,WACA,IA+CA,aACA,wDAEA,6BACA,gBAEA,gDAEA,iDAA2E,CACvE,qBAEJ,kDAEA,sDAA2E,CAC3E,0DAA8E,CAC9E,0DAAgF,CAEhF,6DAAkG,CAC9F,iBACJ,wDAEA,8BAEA,oDAAgF,CAChF,wDAAmF,CACnF,YAEA,CAuCA,eACA,wDAEA,YAMA,+BAMA,8IAEA,qDAAyF,CACzF,qDAA4F,CAE5F,wDAA4F,CAC5F,wDAA+F,CAE/F,2DAAwG,CAExG,YAiCA,iBACA,IAMA,kCAIA,iIAMG,KAKH,+BACA,OAAa,OACb,QAGA,aACA,OAAa,OACb,QAOA,4CACA,SAAoB,+BAEpB,8CACA,gDACA,gDACA,QACA,CAOA,EC/UA,QAIA,cAOA,MAQA,qBACA,QASA,UACA,aAEA,eACA,IAWA,eACA,kBAAqB,CACrB,QAYA,wBACA,MAEA,mBACA,YAEA,UACA,eAGA,wBAEA,iCACA,CACA,UACA,oBACA,KAGA,iBACA,IAgBA,QACA,OACA,qBAGA,2BACA,CACA,UACA,oBAGA,OACA,IA+BA,aACA,sCACA,YAEA,UACA,IAwBA,gBACA,sCACA,YAEA,WACA,IAgBA,aACA,8BACA,kBAGA,8BAGA,OAKA,sBAEA,0CAGA,aACA,GAIA,8BAEA,uCAAwC,mCACxC,UAIA,4CACA,OAKA,mBAGA,oCACA,2BACA,UAGA,sBAGA,QAGA,SACA,KACA,CACA,CAEA,EACA,SAmBA,iBACA,8BACA,kBAGA,8BAGA,OAKA,sBAEA,oCACA,OAKA,WACA,sCAIA,eAEA,oBACA,aAOA,CACA,uCAKA,6BAXA,OACA,GAGA,YAUA,cACA,KACA,CACA,CAEA,EACA,MAmCA,YACA,8BACA,gBAGA,8BAGA,UACA,GAGA,UAGA,oBACA,cAGA,wBAAkD,kCAIlD,kCACA,kDACA,QAKA,6FAEA,0CAIA,UAGA,SAEA,MACA,CAEA,EACA,SASA,kBAEA,2BAGA,mBACA,kCACA,YAEA,6BAGA,6BACA,sBAA8C,CAE9C,YACA,CAIA,ECpeA,mBAKA,iBACA,CAQA,cAcA,cAKA,UACA,qBAEA,kDACA,iFACA,aAuBA,SAAsB,KACtB,qBACA,aACA,gDAEA,gCACA,MAEA,kCAEA,wCAEI,kBACJ,oDACA,2BAEA,iBAEA,gCAEA,yCAGA,aACA,CACA,EuVjGA,EAEA,SASA,OACA,mBAIA,OACA,cACA,WACA,SAGA,gCAAiC,qCAEjC,mCAAiC,qCAGjC,8CACA,aACA,4BAGA,qBACA,yBACA,sBACA,mBACA,gCAGA,qCACA,aACA,oBCpCA,MACA,mBAIA,sBACA,OACA,IAIA,wBACA,OACA,MAIA,OACA,cACA,WACA,mBACA,UAEA,+CACA,SACA,UAUA,aATA,SACA,gBACA,EACA,YAEA,qDAEA,qDACA,UAGA,sBACA,OC3CA,EAEA,SASA,SACA,mBAIA,OACA,cACA,WACA,SAGA,gCAAiC,qCAEjC,mCAAiC,qCAGjC,8CACA,aACA,4BAGA,gBACA,yBACA,kBACA,mBACA,iCAGA,qCACA,aACA,oBCpCA,MACA,mBAIA,sBACA,OACA,IAIA,wBACA,OACA,QAIA,OACA,cACA,WACA,mBACA,YAEA,iDACA,SACA,UAUA,aATA,SACA,kBACA,EACA,YAEA,qDAEA,qDACA,YAGA,sBACA,SACA,EzVnCA,mBAYA,UACA,iBACA,gCACA,eAYA,SAAsB,KACtB,qBACA,aACA,oBACA,iCAEA,0CACA,SACA,4BACI,gBACJ,kBAGA,YAGA,cACA,gBACA,CACA,EAQA,YACA,2CAGA,iCACA,MAQA,gBACA,SACA,MAGA,sCACA,iCAEA,cAMA,gCACA,OAaA,kBAEA,8BACA,6BACA,QAMA,6BAJA,6BAKA,iCAEA,QAGA,cADA,SAKA,OACA,mBAKA,kCAEA,UACA,SACA,EASA,iBACA,MAGA,mCACA,YAGA,oBAEA,gBAGA,aACA,OAMA,sBACA,SACA,2BAOA,qBACA,EClKA,mBAIA,OACA,cACA,oBAEA,mCAEA,0BACA,sBAAiB,0BACjB,kBAAiB,sBAEjB,+BACA,yBACA,wBAEA,oDACA,yBACA,wBACA,aAKA,YACA,8BAIA,iBACA,qBACA,MACA,kBACA,aAGA,8BACA,wCyV1CA,MACA,mBAIA,sBACA,OACA,IAIA,wBACA,OACA,YAIA,OACA,cACA,WACA,mBACA,0DACA,SACA,UAUA,aATA,SACA,uBACA,EAGA,qDAEA,qDACA,gBAEA,EAIA,YACA,cACA,wBAMA,oEACA,qBACA,yCACA,6CACA,4BACA,uCACA,yBACA,mBAEA,OACA,EACA,ExVjEA,SAIA,uBACA,QAQA,mBACA,IACA,mBAGA,4BACA,mBAGA,6BACA,mBAQA,gDAQA,aAQA,cACA,aASA,cACA,kCAEA,MACA,IASA,WACA,iCAEA,MACA,IAKA,QACA,UACA,OAQA,OACA,aACA,uBAEA,2BACA,cAOA,kBACA,YAEA,mCACA,4DACA,sBAEA,YACA,KAOA,sBACA,cA4BA,kBACA,UACA,SA7BA,YAEA,iCACA,+CAGA,YACA,kDACA,GACA,uCACA,SACA,iBAGA,QAGA,iCACA,WACA,WAEA,mBACA,4CAEA,MAEA,EAUA,eACA,YACA,iBAEA,gCAEA,yBACA,+BACA,WACA,WAEA,uBACA,qBAGA,OACA,IAEA,oCACA,mDAEA,YACA,OACA,EAeA,EAWA,SyV3MA,SAAyB,uBAOzB,gBACA,QAWA,oBACA,IACA,mBAcA,kDAMA,gBAMA,iCACA,eAOA,OACA,oBACA,sBACA,kBAGA,wBACA,aASA,gBARA,gBACA,QAKA,UAUA,gBACA,2BACA,YAEA,kCAEA,yCACA,WACA,WAEA,uBACA,QAGA,wCAEA,aACA,MAEA,oCACA,mDAEA,YACA,MACA,EAOA,mBACA,+EACA,gBAOA,kBACA,oBACA,iBAYA,sBACA,SAEA,qBACA,MACA,ECpIA,SACA,mBAIA,OACA,cACA,WAEA,eAEA,8BACA,gBAkBA,iBACA,2BAWA,0CACA,0BAKA,oCAEA,qBACA,OACA,EAEA,GCjDA,SACA,mBAIA,sBACA,OACA,OAKA,OACA,cAEA,mBAEA,YACA,UAMA,yCAEA,oDACA,iBAEA,kBAKA,EACA,QACA,iBACA,MAEA,qBACA,QAEA,SACA,gEAEA,6CACA,2BACA,6BACA,QAEA,qBACA,MAEA,QACA,mBACA,OAIA,EACA,GzVzDA,eDdA,KAOA,iBACA,IACA,mBAGA,6BACA,mBASA,qCAQA,cACA,aA0BA,UACA,kCACA,YwV7DA,GvVgJA,YASA,SC9IA,QAIA,cACA,MACA,SAQA,OACA,cAGA,WACA,QACA,+BAGA,UACA,gCACA,CACA,gBAGA,iBAQA,UACA,cAEA,WACA,QACA,+BAGA,UACA,gCACA,CACA,gBAGA,iBASA,qBACA,cACA,mCAGA,aAKA,QACA,gBAKA,SAEA,gBACA,SAGA,eACA,KAQA,qBACA,cACA,4BAGA,SACA,gBAEA,EACA,EAQqB,SCtHrB,gBACA,sBAOA,YAOA,eAOA,+BCXA,WCMA,mBAIA,OACA,cACA,WACA,aACA,WACA,SACA,YAEA,iBACA,6BACA,yBACA,MACA,QAKA,yCAEA,wBAEA,oEAEA,2EACA,qBACA,GACA,cACA,aACA,UACA,GACA,cACA,aAEA,UACA,GACA,cACA,aAEA,0CACA,MACA,gBAAwB,KACf,qCAAoD,oBAC7D,4CAAmE,UACnE,sCAAkE,UAIlE,qCACA,MACA,gBAAwB,KACf,iBAAa,CAAqB,sCAC3C,KACA,2BAGA,uCACA,MACA,gBAAwB,QACf,iBAAa,CAAwB,wCAC9C,SAA2B,qBAC3B,iCACA,kCAEA,UACA,KACA,SAEA,QAEA,qCACA,KASY,EC3FZ,mBACA,eACA,CAEA,2BACA,WAEA,cACA,aACA,OAcA,oBCxBA,MAEA,YAUA,UACA,mBAIA,wBACA,OACA,QAKA,OACA,6BAQA,iCAIA,+DAEA,MAEA,4CACA,kBAEA,sCACA,6BACA,WAEA,sBACA,UACA,sCAGA,OACA,mBAAqC,OAGrC,QAEA,CAAG,EAAG,UAGN,UACA,sEAGA,+DAAsF,UACtF,QASA,kBACA,cACA,mBACA,aAGA,UACA,MAIA,WACA,YAEA,iBACA,IAIA,SAGA,mBACA,aAIA,iCAEA,gDACA,MACA,2BACA,EASA,gBACA,WACA,+CACA,cAIA,MACA,aACG,iBACH,aACG,oBACH,uDAIA,2BACA,mBAEA,OASA,iBAEA,gBACA,WAGA,2BACA,aAGA,gBACA,YAGA,oBAEA,oCACA,KAiBA,4BAhBA,WACA,2BAGA,kBACA,MACA,SAEA,SACA,SAEA,MACA,2BAEA,KAUA,oBACA,qBACA,aACA,WACA,cAGA,iDACA,iCACA,8DAGA,YAMA,+BALA,aACA,IAGA,KAKA,OACA,YAGA,oBAEA,+EACA,MAMA,4BALA,MACA,2BAEA,KAYA,kCACA,qBACA,aACA,cACA,WAEA,4CAIA,+BACA,GACA,QAGA,MAQA,oBACA,qBACA,aACA,wBACA,YACA,SAEA,cAIA,iCACA,mCAEA,QAKA,4BAJA,iBACA,aAEA,KAGA,CACA,QAQA,4BACA,8CACA,aAWA,oCACA,qBACA,aACA,WACA,wBAIA,UACA,2CAA0C,uBAC1C,kDAEA,kDAIA,QACA,IAMA,kCACA,qBACA,sBAGA,yCACA,OAMa,EC/Ub,mBAYA,UACA,wCAEA,oCAEA,uCACA,uBAIA,MAWA,WACA,qBACA,uBAEA,0CACA,oBAEA,iCACA,SACA,EmV1CA,EACA,mBAIA,OACA,6DACA,QACA,EjVTA,mBAIA,eACA,CAQA,kBAQA,iBAEA,oBAEA,8BACA,KACA,mBACA,CAGA,4BAEA,iBACA,CACA,WAIA,WkVrCA,EACA,mBAOA,iBACA,CAEA,iBAAyB,eAQzB,YAQA,kBAQA,kBAOA,qCAOA,wCAEA,mCAEA,8BACA,KACA,iBACA,OACA,mBAGA,0BACA,MACA,eAGA,YASA,oBACA,qBAEA,QAIA,SAHA,6BAEA,UAWA,sBACA,oBAEA,QAKA,SAJA,wBACA,8BAEA,OAMA,SACA,gBACA,QAKA,QACA,gBACA,OCpHA,EACA,mBAIA,eACA,CAQA,kBAQA,kBAQA,eAQA,wBAEA,8BAEA,8BACA,KACA,mBACA,MACA,OAIA,2CACA,uBACA,6BACA,yBAGA,WAKA,SACA,cACA,QAKA,QACA,cACA,OACA,EjVjEA,mBAIA,eACA,CACA,6BAOA,oBAOA,uBAMA,8BAMA,mEACA,kCAMA,8DAQA,2BAQA,gCACA,iBACA,8BACA,mCACA,mBAEA,eAEA,wBAGA,4CAA4C,YAAc,CAC1D,+CACA,KACA,kBACA,CAEA,6CAEA,eACA,MACA,aACA,KACA,iBAAiC,CACjC,uDACA,MACA,oBAKA,qBAIA,SACA,OACA,uCACA,YAAuB,MACvB,OACA,MACA,kBACA,oBACA,+BAEA,kBAEA,+BACA,QACA,EASA,mBACA,qBACA,QAMA,SALA,UAEA,wCAEA,SAQA,0BACA,qBACA,gBACA,WAEA,iBADA,qBAEA,oBCzIA,oBiVQA,MACA,mBAIA,sBACA,OAIA,OAIA,wBACA,OACA,sBAIA,OACA,MACA,qBACA,aAOA,gBACA,cACA,wBACA,4BACA,wDACA,SACA,UAQA,aAPA,SACA,yCACA,EAEA,sCACA,gDACA,cAEA,EAOA,cACA,cACA,mBAOA,2CAMA,yCAEA,mBACA,+CACA,kCAAoD,oDACpD,aACA,aACA,yCACA,MACA,aAEA,0CACA,MACA,cACA,GAEA,gCACA,MACA,gBAEA,YAEA,WAHa,aAGJ,EAAG,UAEZ,WACA,cACA,yBACA,uCACA,2BAEA,aAMA,YACA,UAGA,yBACA,wBACA,qCACA,wCACA,0BACA,WACA,eAQA,mDACA,2BACA,SAOA,aACA,MAGA,uCAEA,mCAEA,QAQA,iBACA,wCACA,KACA,oBCxJA,MACA,mBAIA,sBACA,OACA,UAKA,wBACA,OACA,OAKA,OACA,cACA,uBAMA,oDACA,mBACA,cAEA,MAAI,EAAG,UAEP,QCrCA,EACA,mBAcA,WACA,cACA,WACA,sBACA,YACA,SACA,sBAEA,6BACA,WAGA,mBACA,GAGA,8BACA,YAGA,QAEA,OACA,0BAEA,cAGA,iBAGA,uBACA,wBAEA,aACA,EC7CA,EACA,mBAIA,wBACA,OACA,cAKA,OAEA,+BACA,gBACA,QAAG,EAAG,UACN,UAwBA,eAAgC,KAChC,wBACA,CACA,eACA,sBACA,kBAEA,OAwBA,YAA6B,KAC7B,wBACA,CACA,eACA,mBACA,kBAEA,OA+CA,eAAgC,KAChC,wBACA,CACA,eACA,sBACA,kBAEA,OAYA,qBACA,SAAwB,cAAY,gBAA2B,eAAiB,GAEhF,gBACA,WACA,eACA,oBAEA,IA4CA,ElVxMA,mBAIA,sBACA,OAIA,OAIA,OACA,cACA,WACA,aACA,mBAEA,gBACA,MACA,QACA,+BAEA,kBACA,MACA,QACA,mCAEA,8BAEA,mDAEA,qDAGA,SACA,cAEA,6DACA,sDACA,SACA,MACA,gCACA,CACA,OAEA,eAIA,YACA,SACA,CAEA,uCACA,GACA,gBACA,0BAIA,kCACA,8BACA,wDACA,WACA,sBACA,iBACA,mBAEA,yBACA,uBAEA,UACA,gBAGA,QACA,CAGA,CACA,EASA,UACA,aAyDA,sBACA,0CACA,qDACA,eACA,KACA,gBACA,cA9DA,kBACA,MACA,qBACA,oBACA,6BACA,sDACA,UACA,sBACA,0BACA,8BACA,OACA,SAMA,sBALA,wBACA,8BACA,sDACA,YACA,IACS,aACT,sBACA,sDACA,0DAEA,eACA,iBACA,oBACA,oBACA,QACA,SAGA,SAFA,UAGA,YAAe,OAAe,KAC9B,UACA,MACA,sDACA,CACA,OAGA,SACA,GACA,GAAS,cAET,CACA,mCACA,SACA,2BAGA,WAEA,yBACA,wBACA,SACA,EACA,EAYa,EC9Ib,mBAIA,eACA,CAOA,yBAQA,8BAWA,sDAQA,wDAcA,8CAEA,uBACA,KACA,kBACA,OAEA,kCACA,MACA,gBAIA,mDACA,qBACA,MACA,EAKA,QACA,iBACA,OAQA,EACA,mBAIA,eACA,CAWA,kBAQA,yBAEA,sCAEA,8BACA,KAEA,mBACA,CAGA,yBACA,gBACA,iBACA,8BAGA,0BAEA,iBACA,sDACA,sCAGA,0BACA,EAGA,KAKA,OACA,cACA,OACA,oBkVpKA,MACA,mBAIA,sBACA,OACA,IAIA,OACA,cACA,WAEA,+CACA,SACA,2BACA,eAsBA,aArBA,cACA,UAEA,yCACA,SACA,wBACA,EAEA,iCACA,yBACA,8BACA,uBACA,WACA,+BACA,CACA,OAGA,YACA,CACA,IAEA,EACA,wCjVvCA,MACA,mBAIA,sBACA,OACA,IAEA,eACA,CAQA,0BAAyC,iDACzC,EAEA,OACA,cAGA,kGACA,qGACA,MASA,0BACA,cACA,WACA,sBAEA,qCAIA,6BACA,eACA,gBACA,qCAGA,iCACA,+CACA,kDACA,GAGA,2BADA,QAIA,mBACA,mBAEA,YACA,SAEA,0CACA,iCAGA,yDACA,sBACA,oBACA,QACA,EAEA,CACA,MAGA,SAGA,UAEA,uBAGA,kDACA,+BAGA,EACA,gBAKa,gBCpGb,mBAIA,wBACA,OACA,aAKA,sBACA,OACA,OiVPA,EACA,mBAIA,sBACA,OAKA,UAKA,wBACA,OACA,WACA,EhV5BA,mBAYA,UACA,qBACA,0BAEA,0CACA,wCACA,OAaA,SAAsB,KACtB,qBAEA,8BACA,oBACA,qCAEA,6BACA,mCACA,oBAGA,YACA,EAQa,EC9Cb,mBAIA,wBACA,OACA,WAKA,OACA,cACA,WACA,aACA,SAEA,mCAGA,6CAGA,mCACA,yBACA,uBAGA,gBACA,yBACA,eAUA,2CAAiE,UAEjE,mCAA8D,UAO9D,yCAAuD,UACvD,kDAAgE,UAOhE,oCACA,CAIA,uBACA,OACA,yBAAmD,UACnD,gCACA,cACA,gBACA,IAAG,EAAG,UACN,UAiCA,EACA,4BAmBA,iFAsHA,iBCtPA,mBAOA,iBACA,CAiBA,cACA,cAKA,UACA,2CAEA,+CACA,8EACA,OAWA,SAAsB,KACtB,cACA,WAEA,8BACA,oBACA,iCACA,4BACA,8BAGA,kBACA,kBACA,+BAGA,aACA,EASa,EC5Eb,SAOA,YACA,mBAIA,eACA,CAEA,mCACA,SACA,CAAK,kDACL,wBAAK,kEACL,uBAAK,kEACL,uBAAK,kEAGL,yBAKA,sBACA,OACA,IAKA,OACA,cACA,WACA,SACA,uBAEA,4BAEA,UAEA,kEAGA,mCACA,2BACA,0BAGA,wBACA,2BACA,yBAGA,uDAGA,eAKA,YAGA,cACA,wBACA,wBAGA,4DACA,iDACA,WACA,2BAEA,6BACA,oBAEA,YAEA,E8UlFA,EACA,QAOA,iBAGA,OAKA,gBAEA,MACA,EClBA,SACA,mBAIA,cACA,CAQA,wBAQA,qCAQA,uBASA,gCACA,iBACA,wBACA,mCACA,mBAEA,eAGA,oBAIA,gCACA,KAEA,gBACA,CAMA,4CAEA,OAKA,SACA,OAGA,6BACA,8BAGA,oCACA,yBACA,QAEA,iCACA,4BACA,QAGA,iCACA,QAKA,QACA,mBACA,YAKA,YACA,mBACA,WCvGA,EACA,mBAIA,cACA,CASA,6BAQA,mBAEA,oBAEA,8BACA,KAEA,gBACA,OACA,CACA,qBACA,yBAEA,oCACA,uBAGA,sBACA,CACA,WAIA,cACA,YAqCA,aAKA,SACA,OAEA,wBACA,WACA,WACA,GAEA,gCAGA,6BACA,+BACA,UAKA,QACA,cACA,OCzFA,EACA,mBAIA,mBACA,CAKA,0BACA,YACA,CAYA,sCAgBA,kBAQA,qBAQA,+BAYA,uBAEA,wBACA,KAEA,iBACA,CAKA,gCAKA,OAKA,SACA,OAGA,qDACA,mBACA,MAGA,4CAGA,wCAGA,oCAEA,wBACA,MACA,yBACA,aACA,UAEA,IAGA,yCAEA,kCACA,cACA,UAEA,IAGA,2CACA,MACA,QAEA,GAGA,uBACA,mCACA,QAKA,QACA,iBACA,OChKA,EACA,mBAIA,eACA,CAEA,sBAQA,sBAYA,mCAEA,oCACA,KAEA,iBACA,OACA,CACA,WACA,sCAIA,8CAEA,YAGA,yBAGA,oBACA,oB/U9CA,MACA,mBAIA,sBACA,OAIA,OAIA,wBACA,OACA,SAIA,OACA,cACA,SACA,cACA,uBACA,SACA,MACA,sBACA,4BACA,0BACA,uBACA,eACA,qBACA,cAEA,gCAEA,WACA,SACA,OAEA,gBACA,CACA,YACA,QAEA,gCACA,WACA,4BACA,yBACA,WACA,iBACA,qBAEA,yBACA,OAEA,6CACA,SACA,QAOA,wBAPqC,YAAc,CAEnD,gEACA,oBACA,4BACA,OACA,IAEA,EAYA,uBACA,cACA,WACA,IACA,aACA,2BACA,2BACA,2BAEA,8DACA,aACA,OAKA,eAHA,iBAAyC,YAAW,CAEpD,YAEA,EASa,oBClHb,MAEA,YAGA,UACA,YAUA,mBCNA,gBCQA,mBAIA,OACA,cACA,WACA,qBACA,SACA,WACA,SACA,YAcA,6BAEA,iDACA,kBACA,MACA,iBAEA,oBACA,MACA,iBAEA,uBAEA,gBAEA,wDAEA,uDAEA,6DAEA,qFAAgG,UAEhG,8FAAiH,UAEjH,sEAAsF,UACtF,QAOA,2BACA,6BACA,UAEA,yDACA,+CAGA,0CACA,cACA,yCACA,SACA,UACA,gBAEA,WACA,0BAEA,gBAGA,oCACA,kBAEA,uBAQA,yBACA,SACA,4BACA,YACA,WAEA,uBACA,yBAEA,wBAGA,aACA,CAKA,oB6UzHA,MACA,mBAIA,sBACA,OACA,IAKA,wBACA,OACA,cCfA,EACA,mBAOA,iBACA,CAiBA,cACA,OAKA,UACA,wCAEA,oCAIG,kCACH,0BAEA,uDAEA,KAUA,SAAsB,KACtB,SACA,MAGA,2BACA,uBAEA,0CACA,oBAIA,mBACA,8BAEA,uDAEA,KACA,EACA,gF5UlEA,MACA,mBAIA,sBACA,OACA,IAIA,wBACA,OACA,kBAIA,OACA,cACA,WACA,aACA,WACA,SAEA,wBAKA,iEAGA,oBACA,MACA,mBACA,oBAGA,kBACA,uBACA,oDACA,oDACA,uDACA,uDACA,uDAEA,8EAAkF,UAElF,iBACA,8BAEA,YASA,kBAEA,SACA,+BAEA,wBACA,aACA,cACA,4CACA,uBACA,UAGA,UACA,qBAGA,UAEA,oBACA,oBAiBA,mCACA,qBACA,QACA,qBACA,kCACA,qCACA,yCACA,0CAEA,uBAkBA,EACA,iBAEA,gBACA,MACA,uBACA,0BACA,EAGA,6BACA,MACA,uBACA,qBACA,YAGA,wCACA,MACA,4BACA,6BACA,YAGA,gDACA,MACA,8BACA,yBACA,YAGA,iDACA,MACA,6BACA,8BACA,YAUA,4BACA,gBACA,SACA,UACA,WACA,YAOa,GCzLb,mBAIA,sBACA,OACA,IAKA,wBACA,OACA,YAKA,OACA,cACA,2BAEA,qBACA,aAEA,gBAQA,iBACA,cACA,0BAEA,4CACA,SAEA,UAYA,aAXA,SACA,aACA,KAGA,sCACA,iCAEA,mDAEA,QAEA,E4U1DA,EAYA,mBAIA,sBACA,OACA,IAKA,wBACA,OACA,cAKA,YACA,cACA,sBAGA,sBAUA,+CASA,mCAGA,oCACA,YACA,OAKA,2DAGA,4DACA,MACA,iBAAG,EAAG,UAGN,+DACA,MACA,iBAAG,EAAG,UACN,QAQA,kBACA,cAEA,yBACA,4BAGA,gBAEA,oBAGA,oBANA,cAaA,eACA,cAEA,YACA,WAEA,kCACA,6BACA,WACA,kBACA,MAIA,iBAzGA,oDAgHA,eACA,MAIA,sCACA,SASA,iBACA,wCACA,QCxIA,EACA,mBACA,eACA,CAEA,2BACA,OAEA,cACA,aACA,OCZA,EACA,mBACA,E5UAA,mBAYA,UACA,qBAEA,6CACA,0EACA,WAkBA,WACA,qBACA,aAEA,+BAEA,WAGA,yBACA,WAGA,iDAEA,gDAEA,8BAGA,0BACA,IAEA,KACA,kBAAmC,CAEnC,eAGA,4BACA,aACA,CAAI,KAGJ,+CAEA,qBACA,yBAEA,aACA,CACA,E6U/EA,EACA,mBAIA,UACA,4DACA,WAUA,UACA,qBACA,aAEA,+BAEA,WACA,oEAGA,gBAGA,iBACA,4BAEA,WACA,EC5BA,EACA,mBAIA,OACA,cACA,WACA,SAGA,gCAAiC,6CAEjC,mCAAiC,6CAGjC,8CACA,2BACA,2BACA,oBAA+C,CAG/C,SAGA,kBADA,GAIA,cAEA,kBAAW,oBAAwB,MACnC,0BACA,KACA,gCAIA,iCACA,mCACA,UCvCA,EACA,mBAIA,eACA,CACA,mBAOA,oBAOA,uBAMA,8BAMA,2DACA,kCAMA,8DAMA,+DAQA,2BAQA,gCACA,iBACA,8BACA,mCACA,mBAEA,eAEA,wBAGA,4CAA4C,YAAc,CAC1D,+CACA,KACA,kBACA,CAEA,gCAEA,eACA,MACA,aACA,KACA,iBAAiC,CACjC,0CACA,MACA,oBACA,sBAKA,qBAIA,SACA,OACA,YAAuB,MACvB,eACA,MACA,kBACA,oBACA,sBAEA,iCAEA,kBAEA,+BACA,QAEA,iCACA,QAIA,QACA,mBACA,YAOA,kBACA,qBACA,gBACA,WAGA,iBAFA,oCACA,uBAUA,mBACA,qBACA,QAMA,SALA,UAEA,wCAEA,SAiBA,wC9U5KA,MACA,SAQA,SACA,mBAIA,sBACA,OAIA,OAIA,wBACA,OACA,MAIA,OACA,cACA,sBAMA,mCAOA,sCAEA,aAEA,gCACA,gBAOA,cACA,cACA,kBACA,yBACA,yBACA,UAuBA,yCArBA,iEACA,uCACA,2CAEA,mCACA,mDACA,YACA,cAEA,gCACA,WACA,eACA,cAEA,qCAEA,8CACA,MACA,eACA,GACA,IAQA,2BACA,cACA,wBACA,YAEA,6BAEA,CACA,MACA,gBAEA,cACA,yCACA,SACA,UAUA,SATA,uBACA,kBACA,IACA,eAEA,oCAEA,gDACA,iBAEA,EAOA,iBACA,6BAGA,iCACA,cAGA,kCAEA,YAEA,2CACA,uEACA,0BACA,QAEA,IAAS,EAIT,UAGA,iDACA,kCACA,gBACA,aAEA,IAEA,MACA,cACA,kDACA,8CACA,2BAEA,cAOA,cACA,cACA,wBACA,yBACA,cACA,YACA,mBACA,mBACA,uDACA,cACA,wCACA,eAMA,IACA,WAQA,iDAEA,0BACA,8BAEA,8CACA,qCAGA,4BACA,WACA,uBAGA,0DAIA,qDAOA,sEACA,EASA,cACA,6CACA,qCAIA,wCAEA,oDACA,oCACA,UAWA,0BACA,6BACA,YACA,4BACA,iBACA,0DACA,uBAAgB,CAChB,SAYA,0BACA,kCACA,eACA,wBACS,wBAGT,2BACA,oBACA,cACA,eACA,iCAMA,aAEA,KALA,IAMA,CAMsD,ECrStD,mBAOA,iBACA,CAQA,4CASA,UAKA,UACA,iBACA,gCACA,eAUA,SAAsB,KACtB,qBACA,kCACA,wCAGA,qBAGA,2BACA,oBAIA,aAEA,qBACA,YACA,KAkDA,+DAGA,wBAGA,UAEA,MAKA,aAKA,WAAoB,WAGpB,eACA,WAEA,KAEA,mBACA,4CAEA,OAmBA,OAGA,IAEA,eACA,yCACA,+BAKA,mBAGA,IAGA,WACA,UAMA,kBACA,aAGA,8BACK,gBAGL,uEAIA,mCAGA,6EANK,WAOL,EAQA,YAEA,2CAEA,+EACA,IAQA,gBAEA,SACA,MAGA,sCACA,iCAEA,cAOA,gCACA,OAUkB,ECzPlB,mBAQA,iBACA,CASA,wCACA,CAKA,UACA,qBACA,eAOA,UACA,qBACA,aACA,qCAEA,0CACA,oBAGA,eAGA,2EACA,aAEA,YAOA,YACA,uBAGA,4BACA,uCAIA,UAIA,eAIA,8BAEA,WAIA,CACA,uBAGA,oBACA,QAEA,OACA,EAQA,gBAEA,2CAGA,kCACA,YAGA,6BAGA,wBACA,2BAEA,oBAEA,kEACA,mBAKA,mCAGA,eACA,eAGA,CACA,QAGA,CACA,QAIA,ECpIA,mBAQA,iBACA,OAKA,eACA,kBAKyB,EEDzB,mBAIA,sBACA,OACA,IAKA,OACA,cAMA,oBACA,iCACA,kBACA,MACA,kBACA,QAEA,mDAGA,wCACA,SAEA,kEAAoF,UAIpF,mDACA,IACA,iCACA,gBACA,sBAIA,qBAAG,EAAG,UAEN,4CACA,4CAEA,qBACA,sCACA,sCAEA,uDAA6D,UAC7D,0BACA,mDAA0D,UAC1D,0BAIA,uCACA,qDAEA,qDACA,mDAA0D,UAC1D,yBACA,mDAAuD,UAEvD,yBACA,uDAEA,uEAAiD,UACjD,0CAAiD,UACjD,0CAAqD,UACrD,0BAGA,yCAAoD,UAGpD,gDACA,oDAGA,kDACA,kDACA,YACA,wC0UxGA,MACA,mBAIA,sBACA,OACA,IAIA,wBACA,OACA,MAIA,OAEA,qBACA,uDACA,wDAGA,yDACA,qBACA,yCACA,sDACA,8BACA,iBACA,mBAEA,OAGA,0DAEA,IAGA,uDACA,eAGA,uBACA,wBAGA,qBACA,UAGA,gDAIA,4DACA,iBACA,mBACA,WAAS,EAAG,UACZ,iBACA,YACA,8BACA,SACA,wBACA,WAEA,IAEA,qCACA,wDACA,eASA,kBACA,cACA,oBACA,wCACA,SACA,UAUA,aATA,CACA,QACA,OAGA,qDAEA,6CACA,aAEA,EC9FA,EAEA,qCAEA,SACA,SAkBA,yDACA,SACA,CAYA,0GACA,CAQA,uFCnEA,GAGA,aACA,OACA,KAAC,IAED,GAEA,0CACA,OAAC,SAED,CACA,4BACA,OAI4C,CAE5C,2BCdA,iBACA,WACA,+BACA,IAEA,4DCPA,GAMA,iEACA,SAIA,oCAKA,yBAKA,6BAmBA,6BACA,OACA,eAEA,yDChCA,iBACA,WACA,kBACA,CACA,QACA,CAEA,kBCrBA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAAyvb,4tbAEzvb,iBCKA,CAEA,qBAEA,0CAEA,YACA,mBAIA,2CACA,mBAGA,iCACA,wCA4BA,oFAEA,OACA,EACA,uCAAwC,CAAW,QACnD,mCAAwC,CAAW,QAGnD,qDACA,QAIA,YAEA,YAGG,sBAEH,mBAGA,wBAIA,6BACA,GAGA,GACA,uBCxFA,U,yPCAA,U,0PCAA,U,qoCCAA,U,uqBCAA,U,g+BCEA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAAkI,2GAElI,qBCLA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAAggB,yeAEhgB,kBCPA,U,qnECEA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAAkd,2bAEld,qBCLA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAAqrB,8pBAErrB,kBCPA,U,ilBCAA,U,sTCEA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAAqrB,4pBAErrB,qBCLA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAA6T,sSAE7T,qBCLA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAA8H,uGAE9H,qBCLA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAAsJ,+HAEtJ,kBCPA,U,0JCAA,U,oMCAA,U,uQCAA,U,yNCAA,U,6rBCEA,CACA,QACA,mCACA,MACA,SAEA,EACA,EAEA,cACA,+BAaA,4BCzBA,cAIA,WACA,YAAwa,iZAExa,kBCPA,U,ixBCAA,U","file":"ckeditor.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"BalloonEditor\"] = factory();\n\telse\n\t\troot[\"BalloonEditor\"] = factory();\n})(this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 4);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 68c4dd51e9faa983488b","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\nmodule.exports = function(useSourceMap) {\n\tvar list = [];\n\n\t// return the list of modules as css string\n\tlist.toString = function toString() {\n\t\treturn this.map(function (item) {\n\t\t\tvar content = cssWithMappingToString(item, useSourceMap);\n\t\t\tif(item[2]) {\n\t\t\t\treturn \"@media \" + item[2] + \"{\" + content + \"}\";\n\t\t\t} else {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t}).join(\"\");\n\t};\n\n\t// import a list of modules into the list\n\tlist.i = function(modules, mediaQuery) {\n\t\tif(typeof modules === \"string\")\n\t\t\tmodules = [[null, modules, \"\"]];\n\t\tvar alreadyImportedModules = {};\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar id = this[i][0];\n\t\t\tif(typeof id === \"number\")\n\t\t\t\talreadyImportedModules[id] = true;\n\t\t}\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar item = modules[i];\n\t\t\t// skip already imported module\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t// when a module is imported multiple times with different media queries.\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\tif(mediaQuery && !item[2]) {\n\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t} else if(mediaQuery) {\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t}\n\t\t\t\tlist.push(item);\n\t\t\t}\n\t\t}\n\t};\n\treturn list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n\tvar content = item[1] || '';\n\tvar cssMapping = item[3];\n\tif (!cssMapping) {\n\t\treturn content;\n\t}\n\n\tif (useSourceMap && typeof btoa === 'function') {\n\t\tvar sourceMapping = toComment(cssMapping);\n\t\tvar sourceURLs = cssMapping.sources.map(function (source) {\n\t\t\treturn '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'\n\t\t});\n\n\t\treturn [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n\t}\n\n\treturn [content].join('\\n');\n}\n\n// Adapted from convert-source-map (MIT)\nfunction toComment(sourceMap) {\n\t// eslint-disable-next-line no-undef\n\tvar base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n\tvar data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;\n\n\treturn '/*# ' + data + ' */';\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader/lib/css-base.js\n// module id = 0\n// module chunks = 0","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n\nvar stylesInDom = {};\n\nvar\tmemoize = function (fn) {\n\tvar memo;\n\n\treturn function () {\n\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\treturn memo;\n\t};\n};\n\nvar isOldIE = memoize(function () {\n\t// Test for IE <= 9 as proposed by Browserhacks\n\t// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n\t// Tests for existence of standard globals is to allow style-loader\n\t// to operate correctly into non-standard environments\n\t// @see https://github.com/webpack-contrib/style-loader/issues/177\n\treturn window && document && document.all && !window.atob;\n});\n\nvar getElement = (function (fn) {\n\tvar memo = {};\n\n\treturn function(selector) {\n\t\tif (typeof memo[selector] === \"undefined\") {\n\t\t\tmemo[selector] = fn.call(this, selector);\n\t\t}\n\n\t\treturn memo[selector]\n\t};\n})(function (target) {\n\treturn document.querySelector(target)\n});\n\nvar singleton = null;\nvar\tsingletonCounter = 0;\nvar\tstylesInsertedAtTop = [];\n\nvar\tfixUrls = require(\"./urls\");\n\nmodule.exports = function(list, options) {\n\tif (typeof DEBUG !== \"undefined\" && DEBUG) {\n\t\tif (typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t}\n\n\toptions = options || {};\n\n\toptions.attrs = typeof options.attrs === \"object\" ? options.attrs : {};\n\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n\t// tags it will allow on a page\n\tif (!options.singleton) options.singleton = isOldIE();\n\n\t// By default, add <style> tags to the <head> element\n\tif (!options.insertInto) options.insertInto = \"head\";\n\n\t// By default, add <style> tags to the bottom of the target\n\tif (!options.insertAt) options.insertAt = \"bottom\";\n\n\tvar styles = listToStyles(list, options);\n\n\taddStylesToDom(styles, options);\n\n\treturn function update (newList) {\n\t\tvar mayRemove = [];\n\n\t\tfor (var i = 0; i < styles.length; i++) {\n\t\t\tvar item = styles[i];\n\t\t\tvar domStyle = stylesInDom[item.id];\n\n\t\t\tdomStyle.refs--;\n\t\t\tmayRemove.push(domStyle);\n\t\t}\n\n\t\tif(newList) {\n\t\t\tvar newStyles = listToStyles(newList, options);\n\t\t\taddStylesToDom(newStyles, options);\n\t\t}\n\n\t\tfor (var i = 0; i < mayRemove.length; i++) {\n\t\t\tvar domStyle = mayRemove[i];\n\n\t\t\tif(domStyle.refs === 0) {\n\t\t\t\tfor (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();\n\n\t\t\t\tdelete stylesInDom[domStyle.id];\n\t\t\t}\n\t\t}\n\t};\n};\n\nfunction addStylesToDom (styles, options) {\n\tfor (var i = 0; i < styles.length; i++) {\n\t\tvar item = styles[i];\n\t\tvar domStyle = stylesInDom[item.id];\n\n\t\tif(domStyle) {\n\t\t\tdomStyle.refs++;\n\n\t\t\tfor(var j = 0; j < domStyle.parts.length; j++) {\n\t\t\t\tdomStyle.parts[j](item.parts[j]);\n\t\t\t}\n\n\t\t\tfor(; j < item.parts.length; j++) {\n\t\t\t\tdomStyle.parts.push(addStyle(item.parts[j], options));\n\t\t\t}\n\t\t} else {\n\t\t\tvar parts = [];\n\n\t\t\tfor(var j = 0; j < item.parts.length; j++) {\n\t\t\t\tparts.push(addStyle(item.parts[j], options));\n\t\t\t}\n\n\t\t\tstylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};\n\t\t}\n\t}\n}\n\nfunction listToStyles (list, options) {\n\tvar styles = [];\n\tvar newStyles = {};\n\n\tfor (var i = 0; i < list.length; i++) {\n\t\tvar item = list[i];\n\t\tvar id = options.base ? item[0] + options.base : item[0];\n\t\tvar css = item[1];\n\t\tvar media = item[2];\n\t\tvar sourceMap = item[3];\n\t\tvar part = {css: css, media: media, sourceMap: sourceMap};\n\n\t\tif(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});\n\t\telse newStyles[id].parts.push(part);\n\t}\n\n\treturn styles;\n}\n\nfunction insertStyleElement (options, style) {\n\tvar target = getElement(options.insertInto)\n\n\tif (!target) {\n\t\tthrow new Error(\"Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.\");\n\t}\n\n\tvar lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];\n\n\tif (options.insertAt === \"top\") {\n\t\tif (!lastStyleElementInsertedAtTop) {\n\t\t\ttarget.insertBefore(style, target.firstChild);\n\t\t} else if (lastStyleElementInsertedAtTop.nextSibling) {\n\t\t\ttarget.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);\n\t\t} else {\n\t\t\ttarget.appendChild(style);\n\t\t}\n\t\tstylesInsertedAtTop.push(style);\n\t} else if (options.insertAt === \"bottom\") {\n\t\ttarget.appendChild(style);\n\t} else {\n\t\tthrow new Error(\"Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.\");\n\t}\n}\n\nfunction removeStyleElement (style) {\n\tif (style.parentNode === null) return false;\n\tstyle.parentNode.removeChild(style);\n\n\tvar idx = stylesInsertedAtTop.indexOf(style);\n\tif(idx >= 0) {\n\t\tstylesInsertedAtTop.splice(idx, 1);\n\t}\n}\n\nfunction createStyleElement (options) {\n\tvar style = document.createElement(\"style\");\n\n\toptions.attrs.type = \"text/css\";\n\n\taddAttrs(style, options.attrs);\n\tinsertStyleElement(options, style);\n\n\treturn style;\n}\n\nfunction createLinkElement (options) {\n\tvar link = document.createElement(\"link\");\n\n\toptions.attrs.type = \"text/css\";\n\toptions.attrs.rel = \"stylesheet\";\n\n\taddAttrs(link, options.attrs);\n\tinsertStyleElement(options, link);\n\n\treturn link;\n}\n\nfunction addAttrs (el, attrs) {\n\tObject.keys(attrs).forEach(function (key) {\n\t\tel.setAttribute(key, attrs[key]);\n\t});\n}\n\nfunction addStyle (obj, options) {\n\tvar style, update, remove, result;\n\n\t// If a transform function was defined, run it on the css\n\tif (options.transform && obj.css) {\n\t result = options.transform(obj.css);\n\n\t if (result) {\n\t \t// If transform returns a value, use that instead of the original css.\n\t \t// This allows running runtime transformations on the css.\n\t \tobj.css = result;\n\t } else {\n\t \t// If the transform function returns a falsy value, don't add this css.\n\t \t// This allows conditional loading of css\n\t \treturn function() {\n\t \t\t// noop\n\t \t};\n\t }\n\t}\n\n\tif (options.singleton) {\n\t\tvar styleIndex = singletonCounter++;\n\n\t\tstyle = singleton || (singleton = createStyleElement(options));\n\n\t\tupdate = applyToSingletonTag.bind(null, style, styleIndex, false);\n\t\tremove = applyToSingletonTag.bind(null, style, styleIndex, true);\n\n\t} else if (\n\t\tobj.sourceMap &&\n\t\ttypeof URL === \"function\" &&\n\t\ttypeof URL.createObjectURL === \"function\" &&\n\t\ttypeof URL.revokeObjectURL === \"function\" &&\n\t\ttypeof Blob === \"function\" &&\n\t\ttypeof btoa === \"function\"\n\t) {\n\t\tstyle = createLinkElement(options);\n\t\tupdate = updateLink.bind(null, style, options);\n\t\tremove = function () {\n\t\t\tremoveStyleElement(style);\n\n\t\t\tif(style.href) URL.revokeObjectURL(style.href);\n\t\t};\n\t} else {\n\t\tstyle = createStyleElement(options);\n\t\tupdate = applyToTag.bind(null, style);\n\t\tremove = function () {\n\t\t\tremoveStyleElement(style);\n\t\t};\n\t}\n\n\tupdate(obj);\n\n\treturn function updateStyle (newObj) {\n\t\tif (newObj) {\n\t\t\tif (\n\t\t\t\tnewObj.css === obj.css &&\n\t\t\t\tnewObj.media === obj.media &&\n\t\t\t\tnewObj.sourceMap === obj.sourceMap\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tupdate(obj = newObj);\n\t\t} else {\n\t\t\tremove();\n\t\t}\n\t};\n}\n\nvar replaceText = (function () {\n\tvar textStore = [];\n\n\treturn function (index, replacement) {\n\t\ttextStore[index] = replacement;\n\n\t\treturn textStore.filter(Boolean).join('\\n');\n\t};\n})();\n\nfunction applyToSingletonTag (style, index, remove, obj) {\n\tvar css = remove ? \"\" : obj.css;\n\n\tif (style.styleSheet) {\n\t\tstyle.styleSheet.cssText = replaceText(index, css);\n\t} else {\n\t\tvar cssNode = document.createTextNode(css);\n\t\tvar childNodes = style.childNodes;\n\n\t\tif (childNodes[index]) style.removeChild(childNodes[index]);\n\n\t\tif (childNodes.length) {\n\t\t\tstyle.insertBefore(cssNode, childNodes[index]);\n\t\t} else {\n\t\t\tstyle.appendChild(cssNode);\n\t\t}\n\t}\n}\n\nfunction applyToTag (style, obj) {\n\tvar css = obj.css;\n\tvar media = obj.media;\n\n\tif(media) {\n\t\tstyle.setAttribute(\"media\", media)\n\t}\n\n\tif(style.styleSheet) {\n\t\tstyle.styleSheet.cssText = css;\n\t} else {\n\t\twhile(style.firstChild) {\n\t\t\tstyle.removeChild(style.firstChild);\n\t\t}\n\n\t\tstyle.appendChild(document.createTextNode(css));\n\t}\n}\n\nfunction updateLink (link, options, obj) {\n\tvar css = obj.css;\n\tvar sourceMap = obj.sourceMap;\n\n\t/*\n\t\tIf convertToAbsoluteUrls isn't defined, but sourcemaps are enabled\n\t\tand there is no publicPath defined then lets turn convertToAbsoluteUrls\n\t\ton by default. Otherwise default to the convertToAbsoluteUrls option\n\t\tdirectly\n\t*/\n\tvar autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;\n\n\tif (options.convertToAbsoluteUrls || autoFixUrls) {\n\t\tcss = fixUrls(css);\n\t}\n\n\tif (sourceMap) {\n\t\t// http://stackoverflow.com/a/26603875\n\t\tcss += \"\\n/*# sourceMappingURL=data:application/json;base64,\" + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + \" */\";\n\t}\n\n\tvar blob = new Blob([css], { type: \"text/css\" });\n\n\tvar oldSrc = link.href;\n\n\tlink.href = URL.createObjectURL(blob);\n\n\tif(oldSrc) URL.revokeObjectURL(oldSrc);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/style-loader/lib/addStyles.js\n// module id = 1\n// module chunks = 0","import checkGlobal from './_checkGlobal';\n\n/** Used to determine if values are of the language type `Object`. */\nvar objectTypes = {\n 'function': true,\n 'object': true\n};\n\n/** Detect free variable `exports`. */\nvar freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)\n ? exports\n : undefined;\n\n/** Detect free variable `module`. */\nvar freeModule = (objectTypes[typeof module] && module && !module.nodeType)\n ? module\n : undefined;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);\n\n/** Detect free variable `self`. */\nvar freeSelf = checkGlobal(objectTypes[typeof self] && self);\n\n/** Detect free variable `window`. */\nvar freeWindow = checkGlobal(objectTypes[typeof window] && window);\n\n/** Detect `this` as the global object. */\nvar thisGlobal = checkGlobal(objectTypes[typeof this] && this);\n\n/**\n * Used as a reference to the global object.\n *\n * The `this` value is used if it's the global object to avoid Greasemonkey's\n * restricted `window` object, otherwise the `window` object is used.\n */\nvar root = freeGlobal ||\n ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||\n freeSelf || thisGlobal || Function('return this')();\n\nexport default root;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_root.js\n// module id = 2\n// module chunks = 0","module.exports = function(originalModule) {\n\tif(!originalModule.webpackPolyfill) {\n\t\tvar module = Object.create(originalModule);\n\t\t// module.parent = undefined by default\n\t\tif(!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"exports\", {\n\t\t\tenumerable: true,\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/harmony-module.js\n// module id = 3\n// module chunks = 0","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/ckeditorerror\n */\n\n/**\n * URL to the documentation with error codes.\n */\nexport const DOCUMENTATION_URL =\n\t'https://ckeditor5.github.io/docs/nightly/ckeditor5/latest/framework/guides/support/error-codes.html';\n\n/**\n * The CKEditor error class.\n *\n * All errors will be shortened during the minification process in order to reduce the code size.\n * Therefore, all error messages should be documented in the same way as those in {@link module:utils/log}.\n *\n * Read more in the {@link module:utils/log} module.\n *\n * @extends Error\n */\nexport default class CKEditorError extends Error {\n\t/**\n\t * Creates an instance of the CKEditorError class.\n\t *\n\t * Read more about error logging in the {@link module:utils/log} module.\n\t *\n\t * @param {String} message The error message in an `error-name: Error message.` format.\n\t * During the minification process the \"Error message\" part will be removed to limit the code size\n\t * and a link to this error documentation will be added to the `message`.\n\t * @param {Object} [data] Additional data describing the error. A stringified version of this object\n\t * will be appended to the error message, so the data are quickly visible in the console. The original\n\t * data object will also be later available under the {@link #data} property.\n\t */\n\tconstructor( message, data ) {\n\t\tmessage = attachLinkToDocumentation( message );\n\n\t\tif ( data ) {\n\t\t\tmessage += ' ' + JSON.stringify( data );\n\t\t}\n\n\t\tsuper( message );\n\n\t\t/**\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = 'CKEditorError';\n\n\t\t/**\n\t\t * The additional error data passed to the constructor.\n\t\t *\n\t\t * @member {Object}\n\t\t */\n\t\tthis.data = data;\n\t}\n\n\t/**\n\t * Checks if error is an instance of CKEditorError class.\n\t *\n\t * @param {Object} error Object to check.\n\t * @returns {Boolean}\n\t */\n\tstatic isCKEditorError( error ) {\n\t\treturn error instanceof CKEditorError;\n\t}\n}\n\n/**\n * Attaches link to the documentation at the end of the error message.\n *\n * @param {String} message Message to be logged.\n * @returns {String}\n */\nexport function attachLinkToDocumentation( message ) {\n\tconst matchedErrorName = message.match( /^([^:]+):/ );\n\n\tif ( !matchedErrorName ) {\n\t\treturn message;\n\t}\n\n\treturn message + ` Read more: ${ DOCUMENTATION_URL }#${ matchedErrorName[ 1 ] }\\n`;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/ckeditorerror.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* global console */\n\n/**\n * @module utils/log\n */\n\nimport { attachLinkToDocumentation } from './ckeditorerror';\n\n/**\n * The logging module.\n *\n * This object features two functions that should be used across CKEditor code base to log errors and warnings.\n * Despite being an overridable interface for native `console.*` this module serves also the goal to limit the\n * code size of a minified CKEditor package. During minification process the messages will be shortened and\n * links to their documentation will be logged to the console.\n *\n * All errors and warning should be documented in the following way:\n *\n *\t\t/**\n *\t\t * Error thrown when a plugin cannot be loaded due to JavaScript errors, lack of plugins with a given name, etc.\n *\t\t *\n *\t\t * @error plugin-load\n *\t\t * @param pluginName The name of the plugin that could not be loaded.\n *\t\t * @param moduleName The name of the module which tried to load this plugin.\n *\t\t * /\n *\t\tlog.error( 'plugin-load: It was not possible to load the \"{$pluginName}\" plugin in module \"{$moduleName}', {\n *\t\t\tpluginName: 'foo',\n *\t\t\tmoduleName: 'bar'\n *\t\t} );\n *\n * ### Warning vs Error vs Throw\n *\n * * Whenever a potentially incorrect situation occurs, which does not directly lead to an incorrect behavior,\n * log a warning.\n * * Whenever an incorrect situation occurs, but the app may continue working (although perhaps incorrectly),\n * log an error.\n * * Whenever it's really bad and it does not make sense to continue working, throw a {@link module:utils/ckeditorerror~CKEditorError}.\n *\n * @namespace\n */\nconst log = {\n\t/**\n\t * Logs an error to the console.\n\t *\n\t * Read more about error logging in the {@link module:utils/log} module.\n\t *\n\t * @param {String} message The error message in an `error-name: Error message.` format.\n\t * During the minification process the \"Error message\" part will be removed to limit the code size\n\t * and a link to this error documentation will be logged to the console.\n\t * @param {Object} [data] Additional data describing the error.\n\t */\n\terror( message, data ) {\n\t\tconsole.error( attachLinkToDocumentation( message ), data );\n\t},\n\n\t/**\n\t * Logs a warning to the console.\n\t *\n\t * Read more about error logging in the {@link module:utils/log} module.\n\t *\n\t * @param {String} message The warning message in a `warning-name: Warning message.` format.\n\t * During the minification process the \"Warning message\" part will be removed to limit the code size\n\t * and a link to this error documentation will be logged to the console.\n\t * @param {Object} [data] Additional data describing the warning.\n\t */\n\twarn( message, data ) {\n\t\tconsole.warn( attachLinkToDocumentation( message ), data );\n\t}\n};\n\nexport default log;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/log.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/translation-service\n */\n\nlet dictionaries = {};\n\n/**\n * Adds package translations to existing ones.\n * These translations will later be available for {@link module:utils/translation-service~translate translate}.\n *\n *\t\tadd( 'pl', {\n *\t\t\t'OK': 'OK',\n *\t\t\t'Cancel [context: reject]': 'Anuluj'\n *\t\t} );\n *\n * @param {String} lang Target language.\n * @param {Object.<String, String>} translations Translations which will be added to the dictionary.\n */\nexport function add( lang, translations ) {\n\tdictionaries[ lang ] = dictionaries[ lang ] || {};\n\n\tObject.assign( dictionaries[ lang ], translations );\n}\n\n/**\n * Translates string if the translation of the string was previously {@link module:utils/translation-service~add added}\n * to the dictionary. This happens in a multi-language mode were translation modules are created by the bundler.\n *\n * When no translation is defined in the dictionary or the dictionary doesn't exist this function returns\n * the original string without the `'[context: ]'` (happens in development and single-language modes).\n *\n * In a single-language mode (when values passed to `t()` were replaced with target languange strings) the dictionary\n * is left empty, so this function will return the original strings always.\n *\n *\t\ttranslate( 'pl', 'Cancel [context: reject]' );\n *\n * @param {String} lang Target language.\n * @param {String} translationKey String which is going to be translated.\n * @returns {String} Translated sentence.\n */\nexport function translate( lang, translationKey ) {\n\tif ( !hasTranslation( lang, translationKey ) ) {\n\t\treturn translationKey.replace( / \\[context: [^\\]]+\\]$/, '' );\n\t}\n\n\treturn dictionaries[ lang ][ translationKey ];\n}\n\n// Checks whether the dictionary exists and translaiton in that dictionary exists.\nfunction hasTranslation( lang, translationKey ) {\n\treturn (\n\t\t( lang in dictionaries ) &&\n\t\t( translationKey in dictionaries[ lang ] )\n\t);\n}\n\n/**\n * Clears dictionaries for test purposes.\n *\n * @protected\n */\nexport function _clear() {\n\tdictionaries = {};\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/translation-service.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/locale\n */\n\nimport { translate } from './translation-service';\n\n/**\n * Represents the localization services.\n */\nexport default class Locale {\n\t/**\n\t * Creates a new instance of the Locale class.\n\t *\n\t * @param {String} [lang='en'] The language code in [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t */\n\tconstructor( lang ) {\n\t\t/**\n\t\t * The language code in [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.lang = lang || 'en';\n\n\t\t/**\n\t\t * Translates the given string to the {@link #lang}. This method is also availble in {@link module:core/editor/editor~Editor#t} and\n\t\t * {@link module:ui/view~View#t}.\n\t\t *\n\t\t * The strings may contain placeholders (`%<index>`) for values which are passed as the second argument.\n\t\t * `<index>` is the index in the `values` array.\n\t\t *\n\t\t *\t\teditor.t( 'Created file \"%0\" in %1ms.', [ fileName, timeTaken ] );\n\t\t *\n\t\t * This method's context is statically bound to Locale instance,\n\t\t * so it can be called as a function:\n\t\t *\n\t\t *\t\tconst t = this.t;\n\t\t *\t\tt( 'Label' );\n\t\t *\n\t\t * @method #t\n\t\t * @param {String} str The string to translate.\n\t\t * @param {String[]} values Values that should be used to interpolate the string.\n\t\t */\n\t\tthis.t = ( ...args ) => this._t( ...args );\n\t}\n\n\t/**\n\t * Base for the {@link #t} method.\n\t *\n\t * @private\n\t */\n\t_t( str, values ) {\n\t\tlet translatedString = translate( this.lang, str );\n\n\t\tif ( values ) {\n\t\t\ttranslatedString = translatedString.replace( /%(\\d+)/g, ( match, index ) => {\n\t\t\t\treturn ( index < values.length ) ? values[ index ] : match;\n\t\t\t} );\n\t\t}\n\n\t\treturn translatedString;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/locale.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/mix\n */\n\n/**\n * Copies enumerable properties and symbols from the objects given as 2nd+ parameters to the\n * prototype of first object (a constructor).\n *\n *\t\tclass Editor {\n *\t\t\t...\n *\t\t}\n *\n *\t\tconst SomeMixin = {\n *\t\t\ta() {\n *\t\t\t\treturn 'a';\n *\t\t\t}\n *\t\t};\n *\n *\t\tmix( Editor, SomeMixin, ... );\n *\n *\t\tnew Editor().a(); // -> 'a'\n *\n * Note: Properties which already exist in the base class will not be overriden.\n *\n * @param {Function} [baseClass] Class which prototype will be extended.\n * @param {Object} [...mixins] Objects from which to get properties.\n */\nexport default function mix( baseClass, ...mixins ) {\n\tmixins.forEach( mixin => {\n\t\tObject.getOwnPropertyNames( mixin ).concat( Object.getOwnPropertySymbols( mixin ) )\n\t\t\t.forEach( key => {\n\t\t\t\tif ( key in baseClass.prototype ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst sourceDescriptor = Object.getOwnPropertyDescriptor( mixin, key );\n\t\t\t\tsourceDescriptor.enumerable = false;\n\n\t\t\t\tObject.defineProperty( baseClass.prototype, key, sourceDescriptor );\n\t\t\t} );\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/mix.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/spy\n */\n\n/**\n * Creates a spy function (ala Sinon.js) that can be used to inspect call to it.\n *\n * The following are the present features:\n *\n * * spy.called: property set to `true` if the function has been called at least once.\n *\n * @returns {Function} The spy function.\n */\nfunction spy() {\n\treturn function spy() {\n\t\tspy.called = true;\n\t};\n}\n\nexport default spy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/spy.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/uid\n */\n\n/**\n * Returns a unique id. This id is a number (starting from 1) which will never get repeated on successive calls\n * to this method.\n *\n * @returns {String} A number representing the id.\n */\nexport default function uid() {\n\tlet uuid = 'e'; // Make sure that id does not start with number.\n\n\tfor ( let i = 0; i < 8; i++ ) {\n\t\tuuid += Math.floor( ( 1 + Math.random() ) * 0x10000 ).toString( 16 ).substring( 1 );\n\t}\n\n\treturn uuid;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/uid.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/priorities\n */\n\n/**\n * String representing a priority value.\n *\n * @typedef {'highest'|'high'|'normal'|'low'|'lowest'} module:utils/priorities~PriorityString\n */\n\n/**\n * Provides group of constants to use instead of hardcoding numeric priority values.\n *\n * @namespace\n */\nconst priorities = {\n\t/**\n\t * Converts a string with priority name to it's numeric value. If `Number` is given, it just returns it.\n\t *\n\t * @static\n\t * @param {module:utils/priorities~PriorityString|Number} priority Priority to convert.\n\t * @returns {Number} Converted priority.\n\t */\n\tget( priority ) {\n\t\tif ( typeof priority != 'number' ) {\n\t\t\treturn this[ priority ] || this.normal;\n\t\t} else {\n\t\t\treturn priority;\n\t\t}\n\t},\n\n\thighest: 100000,\n\thigh: 1000,\n\tnormal: 0,\n\tlow: -1000,\n\tlowest: -100000\n};\n\nexport default priorities;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/priorities.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/emittermixin\n */\n\nimport EventInfo from './eventinfo';\nimport uid from './uid';\nimport priorities from './priorities';\n\nconst _listeningTo = Symbol( 'listeningTo' );\nconst _emitterId = Symbol( 'emitterId' );\n\n/**\n * Mixin that injects the events API into its host.\n *\n * @mixin EmitterMixin\n * @implements module:utils/emittermixin~Emitter\n */\nconst EmitterMixin = {\n\t/**\n\t * Registers a callback function to be executed when an event is fired.\n\t *\n\t * Events can be grouped in namespaces using `:`.\n\t * When namespaced event is fired, it additionally fires all callbacks for that namespace.\n\t *\n\t *\t\tmyEmitter.on( 'myGroup', genericCallback );\n\t *\t\tmyEmitter.on( 'myGroup:myEvent', specificCallback );\n\t *\n\t *\t\t// genericCallback is fired.\n\t *\t\tmyEmitter.fire( 'myGroup' );\n\t *\t\t// both genericCallback and specificCallback are fired.\n\t *\t\tmyEmitter.fire( 'myGroup:myEvent' );\n\t *\t\t// genericCallback is fired even though there are no callbacks for \"foo\".\n\t *\t\tmyEmitter.fire( 'myGroup:foo' );\n\t *\n\t * An event callback can {@link module:utils/eventinfo~EventInfo#stop stop the event} and\n\t * set the {@link module:utils/eventinfo~EventInfo#return return value} of the {@link #fire} method.\n\t *\n\t * @method #on\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to be called on event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n\t * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n\t * order they were added.\n\t */\n\ton( event, callback, options = {} ) {\n\t\tcreateEventNamespace( this, event );\n\t\tconst lists = getCallbacksListsForNamespace( this, event );\n\t\tconst priority = priorities.get( options.priority );\n\n\t\tcallback = {\n\t\t\tcallback,\n\t\t\tpriority\n\t\t};\n\n\t\t// Add the callback to all callbacks list.\n\t\tfor ( const callbacks of lists ) {\n\t\t\t// Add the callback to the list in the right priority position.\n\t\t\tlet added = false;\n\n\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\tif ( callbacks[ i ].priority < priority ) {\n\t\t\t\t\tcallbacks.splice( i, 0, callback );\n\t\t\t\t\tadded = true;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add at the end, if right place was not found.\n\t\t\tif ( !added ) {\n\t\t\t\tcallbacks.push( callback );\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Registers a callback function to be executed on the next time the event is fired only. This is similar to\n\t * calling {@link #on} followed by {@link #off} in the callback.\n\t *\n\t * @method #once\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to be called on event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n\t * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n\t * order they were added.\n\t */\n\tonce( event, callback, options ) {\n\t\tconst onceCallback = function( event, ...args ) {\n\t\t\t// Go off() at the first call.\n\t\t\tevent.off();\n\n\t\t\t// Go with the original callback.\n\t\t\tcallback.call( this, event, ...args );\n\t\t};\n\n\t\t// Make a similar on() call, simply replacing the callback.\n\t\tthis.on( event, onceCallback, options );\n\t},\n\n\t/**\n\t * Stops executing the callback on the given event.\n\t *\n\t * @method #off\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to stop being called.\n\t */\n\toff( event, callback ) {\n\t\tconst lists = getCallbacksListsForNamespace( this, event );\n\n\t\tfor ( const callbacks of lists ) {\n\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\tif ( callbacks[ i ].callback == callback ) {\n\t\t\t\t\t// Remove the callback from the list (fixing the next index).\n\t\t\t\t\tcallbacks.splice( i, 1 );\n\t\t\t\t\ti--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Registers a callback function to be executed when an event is fired in a specific (emitter) object.\n\t *\n\t * @method #listenTo\n\t * @param {module:utils/emittermixin~Emitter} emitter The object that fires the event.\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to be called on event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n\t * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n\t * order they were added.\n\t */\n\tlistenTo( emitter, event, callback, options ) {\n\t\tlet emitterInfo, eventCallbacks;\n\n\t\t// _listeningTo contains a list of emitters that this object is listening to.\n\t\t// This list has the following format:\n\t\t//\n\t\t// _listeningTo: {\n\t\t// emitterId: {\n\t\t// emitter: emitter,\n\t\t// callbacks: {\n\t\t// event1: [ callback1, callback2, ... ]\n\t\t// ....\n\t\t// }\n\t\t// },\n\t\t// ...\n\t\t// }\n\n\t\tif ( !this[ _listeningTo ] ) {\n\t\t\tthis[ _listeningTo ] = {};\n\t\t}\n\n\t\tconst emitters = this[ _listeningTo ];\n\n\t\tif ( !_getEmitterId( emitter ) ) {\n\t\t\t_setEmitterId( emitter );\n\t\t}\n\n\t\tconst emitterId = _getEmitterId( emitter );\n\n\t\tif ( !( emitterInfo = emitters[ emitterId ] ) ) {\n\t\t\temitterInfo = emitters[ emitterId ] = {\n\t\t\t\temitter,\n\t\t\t\tcallbacks: {}\n\t\t\t};\n\t\t}\n\n\t\tif ( !( eventCallbacks = emitterInfo.callbacks[ event ] ) ) {\n\t\t\teventCallbacks = emitterInfo.callbacks[ event ] = [];\n\t\t}\n\n\t\teventCallbacks.push( callback );\n\n\t\t// Finally register the callback to the event.\n\t\temitter.on( event, callback, options );\n\t},\n\n\t/**\n\t * Stops listening for events. It can be used at different levels:\n\t *\n\t * * To stop listening to a specific callback.\n\t * * To stop listening to a specific event.\n\t * * To stop listening to all events fired by a specific object.\n\t * * To stop listening to all events fired by all object.\n\t *\n\t * @method #stopListening\n\t * @param {module:utils/emittermixin~Emitter} [emitter] The object to stop listening to. If omitted, stops it for all objects.\n\t * @param {String} [event] (Requires the `emitter`) The name of the event to stop listening to. If omitted, stops it\n\t * for all events from `emitter`.\n\t * @param {Function} [callback] (Requires the `event`) The function to be removed from the call list for the given\n\t * `event`.\n\t */\n\tstopListening( emitter, event, callback ) {\n\t\tconst emitters = this[ _listeningTo ];\n\t\tlet emitterId = emitter && _getEmitterId( emitter );\n\t\tconst emitterInfo = emitters && emitterId && emitters[ emitterId ];\n\t\tconst eventCallbacks = emitterInfo && event && emitterInfo.callbacks[ event ];\n\n\t\t// Stop if nothing has been listened.\n\t\tif ( !emitters || ( emitter && !emitterInfo ) || ( event && !eventCallbacks ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// All params provided. off() that single callback.\n\t\tif ( callback ) {\n\t\t\temitter.off( event, callback );\n\t\t}\n\t\t// Only `emitter` and `event` provided. off() all callbacks for that event.\n\t\telse if ( eventCallbacks ) {\n\t\t\twhile ( ( callback = eventCallbacks.pop() ) ) {\n\t\t\t\temitter.off( event, callback );\n\t\t\t}\n\t\t\tdelete emitterInfo.callbacks[ event ];\n\t\t}\n\t\t// Only `emitter` provided. off() all events for that emitter.\n\t\telse if ( emitterInfo ) {\n\t\t\tfor ( event in emitterInfo.callbacks ) {\n\t\t\t\tthis.stopListening( emitter, event );\n\t\t\t}\n\t\t\tdelete emitters[ emitterId ];\n\t\t}\n\t\t// No params provided. off() all emitters.\n\t\telse {\n\t\t\tfor ( emitterId in emitters ) {\n\t\t\t\tthis.stopListening( emitters[ emitterId ].emitter );\n\t\t\t}\n\t\t\tdelete this[ _listeningTo ];\n\t\t}\n\t},\n\n\t/**\n\t * Fires an event, executing all callbacks registered for it.\n\t *\n\t * The first parameter passed to callbacks is an {@link module:utils/eventinfo~EventInfo} object,\n\t * followed by the optional `args` provided in the `fire()` method call.\n\t *\n\t * @method #fire\n\t * @param {String|module:utils/eventinfo~EventInfo} eventOrInfo The name of the event or `EventInfo` object if event is delegated.\n\t * @param {...*} [args] Additional arguments to be passed to the callbacks.\n\t * @returns {*} By default the method returns `undefined`. However, the return value can be changed by listeners\n\t * through modification of the {@link module:utils/eventinfo~EventInfo#return}'s value (the event info\n\t * is the first param of every callback).\n\t */\n\tfire( eventOrInfo, ...args ) {\n\t\tconst eventInfo = eventOrInfo instanceof EventInfo ? eventOrInfo : new EventInfo( this, eventOrInfo );\n\t\tconst event = eventInfo.name;\n\t\tlet callbacks = getCallbacksForEvent( this, event );\n\n\t\t// Record that the event passed this emitter on its path.\n\t\teventInfo.path.push( this );\n\n\t\t// Handle event listener callbacks first.\n\t\tif ( callbacks ) {\n\t\t\t// Arguments passed to each callback.\n\t\t\tconst callbackArgs = [ eventInfo, ...args ];\n\n\t\t\t// Copying callbacks array is the easiest and most secure way of preventing infinite loops, when event callbacks\n\t\t\t// are added while processing other callbacks. Previous solution involved adding counters (unique ids) but\n\t\t\t// failed if callbacks were added to the queue before currently processed callback.\n\t\t\t// If this proves to be too inefficient, another method is to change `.on()` so callbacks are stored if same\n\t\t\t// event is currently processed. Then, `.fire()` at the end, would have to add all stored events.\n\t\t\tcallbacks = Array.from( callbacks );\n\n\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\tcallbacks[ i ].callback.apply( this, callbackArgs );\n\n\t\t\t\t// Remove the callback from future requests if off() has been called.\n\t\t\t\tif ( eventInfo.off.called ) {\n\t\t\t\t\t// Remove the called mark for the next calls.\n\t\t\t\t\tdelete eventInfo.off.called;\n\n\t\t\t\t\tthis.off( event, callbacks[ i ].callback );\n\t\t\t\t}\n\n\t\t\t\t// Do not execute next callbacks if stop() was called.\n\t\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Delegate event to other emitters if needed.\n\t\tif ( this._delegations ) {\n\t\t\tconst destinations = this._delegations.get( event );\n\t\t\tconst passAllDestinations = this._delegations.get( '*' );\n\n\t\t\tif ( destinations ) {\n\t\t\t\tfireDelegatedEvents( destinations, eventInfo, args );\n\t\t\t}\n\n\t\t\tif ( passAllDestinations ) {\n\t\t\t\tfireDelegatedEvents( passAllDestinations, eventInfo, args );\n\t\t\t}\n\t\t}\n\n\t\treturn eventInfo.return;\n\t},\n\n\t/**\n\t * Delegates selected events to another {@link module:utils/emittermixin~Emitter}. For instance:\n\t *\n\t *\t\temitterA.delegate( 'eventX' ).to( emitterB );\n\t *\t\temitterA.delegate( 'eventX', 'eventY' ).to( emitterC );\n\t *\n\t * then `eventX` is delegated (fired by) `emitterB` and `emitterC` along with `data`:\n\t *\n\t *\t\temitterA.fire( 'eventX', data );\n\t *\n\t * and `eventY` is delegated (fired by) `emitterC` along with `data`:\n\t *\n\t *\t\temitterA.fire( 'eventY', data );\n\t *\n\t * @method #delegate\n\t * @param {...String} events Event names that will be delegated to another emitter.\n\t * @returns {module:utils/emittermixin~EmitterMixinDelegateChain}\n\t */\n\tdelegate( ...events ) {\n\t\treturn {\n\t\t\tto: ( emitter, nameOrFunction ) => {\n\t\t\t\tif ( !this._delegations ) {\n\t\t\t\t\tthis._delegations = new Map();\n\t\t\t\t}\n\n\t\t\t\tfor ( const eventName of events ) {\n\t\t\t\t\tconst destinations = this._delegations.get( eventName );\n\n\t\t\t\t\tif ( !destinations ) {\n\t\t\t\t\t\tthis._delegations.set( eventName, new Map( [ [ emitter, nameOrFunction ] ] ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdestinations.set( emitter, nameOrFunction );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t},\n\n\t/**\n\t * Stops delegating events. It can be used at different levels:\n\t *\n\t * * To stop delegating all events.\n\t * * To stop delegating a specific event to all emitters.\n\t * * To stop delegating a specific event to a specific emitter.\n\t *\n\t * @method #stopDelegating\n\t * @param {String} [event] The name of the event to stop delegating. If omitted, stops it all delegations.\n\t * @param {module:utils/emittermixin~Emitter} [emitter] (requires `event`) The object to stop delegating a particular event to.\n\t * If omitted, stops delegation of `event` to all emitters.\n\t */\n\tstopDelegating( event, emitter ) {\n\t\tif ( !this._delegations ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !event ) {\n\t\t\tthis._delegations.clear();\n\t\t} else if ( !emitter ) {\n\t\t\tthis._delegations.delete( event );\n\t\t} else {\n\t\t\tconst destinations = this._delegations.get( event );\n\n\t\t\tif ( destinations ) {\n\t\t\t\tdestinations.delete( emitter );\n\t\t\t}\n\t\t}\n\t}\n};\n\nexport default EmitterMixin;\n\n/**\n * Checks if `listeningEmitter` listens to an emitter with given `listenedToEmitterId` and if so, returns that emitter.\n * If not, returns `null`.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} listeningEmitter Emitter that listens.\n * @param {String} listenedToEmitterId Unique emitter id of emitter listened to.\n * @returns {module:utils/emittermixin~EmitterMixin|null}\n */\nexport function _getEmitterListenedTo( listeningEmitter, listenedToEmitterId ) {\n\tif ( listeningEmitter[ _listeningTo ] && listeningEmitter[ _listeningTo ][ listenedToEmitterId ] ) {\n\t\treturn listeningEmitter[ _listeningTo ][ listenedToEmitterId ].emitter;\n\t}\n\n\treturn null;\n}\n\n/**\n * Sets emitter's unique id.\n *\n * **Note:** `_emitterId` can be set only once.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} emitter Emitter for which id will be set.\n * @param {String} [id] Unique id to set. If not passed, random unique id will be set.\n */\nexport function _setEmitterId( emitter, id ) {\n\tif ( !emitter[ _emitterId ] ) {\n\t\temitter[ _emitterId ] = id || uid();\n\t}\n}\n\n/**\n * Returns emitter's unique id.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} emitter Emitter which id will be returned.\n */\nexport function _getEmitterId( emitter ) {\n\treturn emitter[ _emitterId ];\n}\n\n// Gets the internal `_events` property of the given object.\n// `_events` property store all lists with callbacks for registered event names.\n// If there were no events registered on the object, empty `_events` object is created.\nfunction getEvents( source ) {\n\tif ( !source._events ) {\n\t\tObject.defineProperty( source, '_events', {\n\t\t\tvalue: {}\n\t\t} );\n\t}\n\n\treturn source._events;\n}\n\n// Creates event node for generic-specific events relation architecture.\nfunction makeEventNode() {\n\treturn {\n\t\tcallbacks: [],\n\t\tchildEvents: []\n\t};\n}\n\n// Creates an architecture for generic-specific events relation.\n// If needed, creates all events for given eventName, i.e. if the first registered event\n// is foo:bar:abc, it will create foo:bar:abc, foo:bar and foo event and tie them together.\n// It also copies callbacks from more generic events to more specific events when\n// specific events are created.\nfunction createEventNamespace( source, eventName ) {\n\tconst events = getEvents( source );\n\n\t// First, check if the event we want to add to the structure already exists.\n\tif ( events[ eventName ] ) {\n\t\t// If it exists, we don't have to do anything.\n\t\treturn;\n\t}\n\n\t// In other case, we have to create the structure for the event.\n\t// Note, that we might need to create intermediate events too.\n\t// I.e. if foo:bar:abc is being registered and we only have foo in the structure,\n\t// we need to also register foo:bar.\n\n\t// Currently processed event name.\n\tlet name = eventName;\n\t// Name of the event that is a child event for currently processed event.\n\tlet childEventName = null;\n\n\t// Array containing all newly created specific events.\n\tconst newEventNodes = [];\n\n\t// While loop can't check for ':' index because we have to handle generic events too.\n\t// In each loop, we truncate event name, going from the most specific name to the generic one.\n\t// I.e. foo:bar:abc -> foo:bar -> foo.\n\twhile ( name !== '' ) {\n\t\tif ( events[ name ] ) {\n\t\t\t// If the currently processed event name is already registered, we can be sure\n\t\t\t// that it already has all the structure created, so we can break the loop here\n\t\t\t// as no more events need to be registered.\n\t\t\tbreak;\n\t\t}\n\n\t\t// If this event is not yet registered, create a new object for it.\n\t\tevents[ name ] = makeEventNode();\n\t\t// Add it to the array with newly created events.\n\t\tnewEventNodes.push( events[ name ] );\n\n\t\t// Add previously processed event name as a child of this event.\n\t\tif ( childEventName ) {\n\t\t\tevents[ name ].childEvents.push( childEventName );\n\t\t}\n\n\t\tchildEventName = name;\n\t\t// If `.lastIndexOf()` returns -1, `.substr()` will return '' which will break the loop.\n\t\tname = name.substr( 0, name.lastIndexOf( ':' ) );\n\t}\n\n\tif ( name !== '' ) {\n\t\t// If name is not empty, we found an already registered event that was a parent of the\n\t\t// event we wanted to register.\n\n\t\t// Copy that event's callbacks to newly registered events.\n\t\tfor ( const node of newEventNodes ) {\n\t\t\tnode.callbacks = events[ name ].callbacks.slice();\n\t\t}\n\n\t\t// Add last newly created event to the already registered event.\n\t\tevents[ name ].childEvents.push( childEventName );\n\t}\n}\n\n// Gets an array containing callbacks list for a given event and it's more specific events.\n// I.e. if given event is foo:bar and there is also foo:bar:abc event registered, this will\n// return callback list of foo:bar and foo:bar:abc (but not foo).\n// Returns empty array if given event has not been yet registered.\nfunction getCallbacksListsForNamespace( source, eventName ) {\n\tconst eventNode = getEvents( source )[ eventName ];\n\n\tif ( !eventNode ) {\n\t\treturn [];\n\t}\n\n\tlet callbacksLists = [ eventNode.callbacks ];\n\n\tfor ( let i = 0; i < eventNode.childEvents.length; i++ ) {\n\t\tconst childCallbacksLists = getCallbacksListsForNamespace( source, eventNode.childEvents[ i ] );\n\n\t\tcallbacksLists = callbacksLists.concat( childCallbacksLists );\n\t}\n\n\treturn callbacksLists;\n}\n\n// Get the list of callbacks for a given event, but only if there any callbacks have been registered.\n// If there are no callbacks registered for given event, it checks if this is a specific event and looks\n// for callbacks for it's more generic version.\nfunction getCallbacksForEvent( source, eventName ) {\n\tlet event;\n\n\tif ( !source._events || !( event = source._events[ eventName ] ) || !event.callbacks.length ) {\n\t\t// There are no callbacks registered for specified eventName.\n\t\t// But this could be a specific-type event that is in a namespace.\n\t\tif ( eventName.indexOf( ':' ) > -1 ) {\n\t\t\t// If the eventName is specific, try to find callback lists for more generic event.\n\t\t\treturn getCallbacksForEvent( source, eventName.substr( 0, eventName.lastIndexOf( ':' ) ) );\n\t\t} else {\n\t\t\t// If this is a top-level generic event, return null;\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn event.callbacks;\n}\n\n// Fires delegated events for given map of destinations.\n//\n// @private\n// * @param {Map.<utils.Emitter>} destinations A map containing `[ {@link utils.Emitter}, \"event name\" ]` pair destinations.\n// * @param {utils.EventInfo} eventInfo The original event info object.\n// * @param {Array.<*>} fireArgs Arguments the original event was fired with.\nfunction fireDelegatedEvents( destinations, eventInfo, fireArgs ) {\n\tfor ( let [ emitter, name ] of destinations ) {\n\t\tif ( !name ) {\n\t\t\tname = eventInfo.name;\n\t\t} else if ( typeof name == 'function' ) {\n\t\t\tname = name( eventInfo.name );\n\t\t}\n\n\t\tconst delegatedInfo = new EventInfo( eventInfo.source, name );\n\n\t\tdelegatedInfo.path = [ ...eventInfo.path ];\n\n\t\temitter.fire( delegatedInfo, ...fireArgs );\n\t}\n}\n\n/**\n * Interface representing classes which mix in {@link module:utils/emittermixin~EmitterMixin}.\n *\n * @interface Emitter\n */\n\n/**\n * The return value of {@link ~EmitterMixin#delegate}.\n *\n * @interface module:utils/emittermixin~EmitterMixinDelegateChain\n */\n\n/**\n * Selects destination for {@link module:utils/emittermixin~EmitterMixin#delegate} events.\n *\n * @method #to\n * @param {module:utils/emittermixin~Emitter} emitter An `EmitterMixin` instance which is the destination for delegated events.\n * @param {String|Function} nameOrFunction A custom event name or function which converts the original name string.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/emittermixin.js\n// module id = null\n// module chunks = ","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'user': 'fred' };\n * var other = { 'user': 'fred' };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/eq.js\n// module id = null\n// module chunks = ","import Reflect from './_Reflect';\nimport iteratorToArray from './_iteratorToArray';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar enumerate = Reflect ? Reflect.enumerate : undefined,\n propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * The base implementation of `_.keysIn` which doesn't skip the constructor\n * property of prototypes or treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n object = object == null ? object : Object(object);\n\n var result = [];\n for (var key in object) {\n result.push(key);\n }\n return result;\n}\n\n// Fallback for IE < 9 with es6-shim.\nif (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {\n baseKeysIn = function(object) {\n return iteratorToArray(enumerate(object));\n };\n}\n\nexport default baseKeysIn;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseKeysIn.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/observablemixin\n */\n\nimport EmitterMixin from './emittermixin';\nimport CKEditorError from './ckeditorerror';\nimport extend from './lib/lodash/extend';\nimport isObject from './lib/lodash/isObject';\n\nconst attributesSymbol = Symbol( 'attributes' );\nconst boundObservablesSymbol = Symbol( 'boundObservables' );\nconst boundAttributesSymbol = Symbol( 'boundAttributes' );\n\n/**\n * Mixin that injects the \"observable attributes\" and data binding functionality.\n * Used mainly in the {@link module:ui/model~Model} class.\n *\n * @mixin ObservableMixin\n * @mixes module:utils/emittermixin~EmitterMixin\n * @implements module:utils/observablemixin~Observable\n */\nconst ObservableMixin = {\n\t/**\n\t * Creates and sets the value of an observable attribute of this object. Such an attribute becomes a part\n\t * of the state and is be observable.\n\t *\n\t * It accepts also a single object literal containing key/value pairs with attributes to be set.\n\t *\n\t * This method throws the observable-set-cannot-override error if the observable instance already\n\t * have a property with a given attribute name. This prevents from mistakenly overriding existing\n\t * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.\n\t *\n\t * @method #set\n\t * @param {String} name The attributes name.\n\t * @param {*} value The attributes value.\n\t */\n\tset( name, value ) {\n\t\t// If the first parameter is an Object, iterate over its properties.\n\t\tif ( isObject( name ) ) {\n\t\t\tObject.keys( name ).forEach( attr => {\n\t\t\t\tthis.set( attr, name[ attr ] );\n\t\t\t}, this );\n\n\t\t\treturn;\n\t\t}\n\n\t\tinitObservable( this );\n\n\t\tconst attributes = this[ attributesSymbol ];\n\n\t\tif ( ( name in this ) && !attributes.has( name ) ) {\n\t\t\t/**\n\t\t\t * Cannot override an existing property.\n\t\t\t *\n\t\t\t * This error is thrown when trying to {@link ~Observable#set set} an attribute with\n\t\t\t * a name of an already existing property. For example:\n\t\t\t *\n\t\t\t *\t\tlet observable = new Model();\n\t\t\t *\t\tobservable.property = 1;\n\t\t\t *\t\tobservable.set( 'property', 2 );\t\t// throws\n\t\t\t *\n\t\t\t *\t\tobservable.set( 'attr', 1 );\n\t\t\t *\t\tobservable.set( 'attr', 2 );\t\t\t// ok, because this is an existing attribute.\n\t\t\t *\n\t\t\t * @error observable-set-cannot-override\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-set-cannot-override: Cannot override an existing property.' );\n\t\t}\n\n\t\tObject.defineProperty( this, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget() {\n\t\t\t\treturn attributes.get( name );\n\t\t\t},\n\n\t\t\tset( value ) {\n\t\t\t\tconst oldValue = attributes.get( name );\n\n\t\t\t\t// Allow undefined as an initial value like A.define( 'x', undefined ) (#132).\n\t\t\t\t// Note: When attributes map has no such own property, then its value is undefined.\n\t\t\t\tif ( oldValue !== value || !attributes.has( name ) ) {\n\t\t\t\t\tattributes.set( name, value );\n\t\t\t\t\tthis.fire( 'change:' + name, name, value, oldValue );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tthis[ name ] = value;\n\t},\n\n\t/**\n\t * Binds observable attributes to another objects implementing {@link ~ObservableMixin}\n\t * interface (like {@link module:ui/model~Model}).\n\t *\n\t * Once bound, the observable will immediately share the current state of attributes\n\t * of the observable it is bound to and react to the changes to these attributes\n\t * in the future.\n\t *\n\t * **Note**: To release the binding use {@link module:utils/observablemixin~ObservableMixin#unbind}.\n\t *\n\t *\t\tA.bind( 'a' ).to( B );\n\t *\t\tA.bind( 'a' ).to( B, 'b' );\n\t *\t\tA.bind( 'a', 'b' ).to( B, 'c', 'd' );\n\t *\t\tA.bind( 'a' ).to( B, 'b', C, 'd', ( b, d ) => b + d );\n\t *\n\t * @method #bind\n\t * @param {...String} bindAttrs Observable attributes that will be bound to another observable(s).\n\t * @returns {module:utils/observablemixin~BindChain}\n\t */\n\tbind( ...bindAttrs ) {\n\t\tif ( !bindAttrs.length || !isStringArray( bindAttrs ) ) {\n\t\t\t/**\n\t\t\t * All attributes must be strings.\n\t\t\t *\n\t\t\t * @error observable-bind-wrong-attrs\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-wrong-attrs: All attributes must be strings.' );\n\t\t}\n\n\t\tif ( ( new Set( bindAttrs ) ).size !== bindAttrs.length ) {\n\t\t\t/**\n\t\t\t * Attributes must be unique.\n\t\t\t *\n\t\t\t * @error observable-bind-duplicate-attrs\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-duplicate-attrs: Attributes must be unique.' );\n\t\t}\n\n\t\tinitObservable( this );\n\n\t\tconst boundAttributes = this[ boundAttributesSymbol ];\n\n\t\tbindAttrs.forEach( attrName => {\n\t\t\tif ( boundAttributes.has( attrName ) ) {\n\t\t\t\t/**\n\t\t\t\t * Cannot bind the same attribute more that once.\n\t\t\t\t *\n\t\t\t\t * @error observable-bind-rebind\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-bind-rebind: Cannot bind the same attribute more that once.' );\n\t\t\t}\n\t\t} );\n\n\t\tconst bindings = new Map();\n\n\t\t/**\n\t\t * @typedef Binding\n\t\t * @type Object\n\t\t * @property {Array} attr Attribute which is bound.\n\t\t * @property {Array} to Array of observableattribute components of the binding (`{ observable: ..., attr: .. }`).\n\t\t * @property {Array} callback A function which processes `to` components.\n\t\t */\n\t\tbindAttrs.forEach( a => {\n\t\t\tconst binding = { attr: a, to: [] };\n\n\t\t\tboundAttributes.set( a, binding );\n\t\t\tbindings.set( a, binding );\n\t\t} );\n\n\t\t/**\n\t\t * @typedef BindChain\n\t\t * @type Object\n\t\t * @property {Function} to See {@link ~ObservableMixin#_bindTo}.\n\t\t * @property {module:utils/observablemixin~Observable} _observable The observable which initializes the binding.\n\t\t * @property {Array} _bindAttrs Array of `_observable` attributes to be bound.\n\t\t * @property {Array} _to Array of `to()` observableattributes (`{ observable: toObservable, attrs: ...toAttrs }`).\n\t\t * @property {Map} _bindings Stores bindings to be kept in\n\t\t * {@link ~ObservableMixin#_boundAttributes}/{@link ~ObservableMixin#_boundObservables}\n\t\t * initiated in this binding chain.\n\t\t */\n\t\treturn {\n\t\t\tto: bindTo,\n\n\t\t\t_observable: this,\n\t\t\t_bindAttrs: bindAttrs,\n\t\t\t_to: [],\n\t\t\t_bindings: bindings\n\t\t};\n\t},\n\n\t/**\n\t * Removes the binding created with {@link ~ObservableMixin#bind}.\n\t *\n\t *\t\tA.unbind( 'a' );\n\t *\t\tA.unbind();\n\t *\n\t * @method #unbind\n\t * @param {...String} [unbindAttrs] Observable attributes to be unbound. All the bindings will\n\t * be released if no attributes provided.\n\t */\n\tunbind( ...unbindAttrs ) {\n\t\t// Nothing to do here if not inited yet.\n\t\tif ( !( attributesSymbol in this ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst boundAttributes = this[ boundAttributesSymbol ];\n\t\tconst boundObservables = this[ boundObservablesSymbol ];\n\n\t\tif ( unbindAttrs.length ) {\n\t\t\tif ( !isStringArray( unbindAttrs ) ) {\n\t\t\t\t/**\n\t\t\t\t * Attributes must be strings.\n\t\t\t\t *\n\t\t\t\t * @error observable-unbind-wrong-attrs\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-unbind-wrong-attrs: Attributes must be strings.' );\n\t\t\t}\n\n\t\t\tunbindAttrs.forEach( attrName => {\n\t\t\t\tconst binding = boundAttributes.get( attrName );\n\t\t\t\tlet toObservable, toAttr, toAttrs, toAttrBindings;\n\n\t\t\t\tbinding.to.forEach( to => {\n\t\t\t\t\t// TODO: ES6 destructuring.\n\t\t\t\t\ttoObservable = to[ 0 ];\n\t\t\t\t\ttoAttr = to[ 1 ];\n\t\t\t\t\ttoAttrs = boundObservables.get( toObservable );\n\t\t\t\t\ttoAttrBindings = toAttrs[ toAttr ];\n\n\t\t\t\t\ttoAttrBindings.delete( binding );\n\n\t\t\t\t\tif ( !toAttrBindings.size ) {\n\t\t\t\t\t\tdelete toAttrs[ toAttr ];\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !Object.keys( toAttrs ).length ) {\n\t\t\t\t\t\tboundObservables.delete( toObservable );\n\t\t\t\t\t\tthis.stopListening( toObservable, 'change' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\tboundAttributes.delete( attrName );\n\t\t\t} );\n\t\t} else {\n\t\t\tboundObservables.forEach( ( bindings, boundObservable ) => {\n\t\t\t\tthis.stopListening( boundObservable, 'change' );\n\t\t\t} );\n\n\t\t\tboundObservables.clear();\n\t\t\tboundAttributes.clear();\n\t\t}\n\t},\n\n\t/**\n\t * Turns the given methods of this object into event-based ones. This means that the new method will fire an event\n\t * (named after the method) and the original action will be plugged as a listener to that event.\n\t *\n\t * This is a very simplified method decoration. Itself it doesn't change the behavior of a method (expect adding the event),\n\t * but it allows to modify it later on by listening to the method's event.\n\t *\n\t * For example, in order to cancel the method execution one can stop the event:\n\t *\n\t *\t\tclass Foo {\n\t *\t\t\tconstructor() {\n\t *\t\t\t\tthis.decorate( 'method' );\n\t *\t\t\t}\n\t *\n\t *\t\t\tmethod() {\n\t *\t\t\t\tconsole.log( 'called!' );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst foo = new Foo();\n\t *\t\tfoo.on( 'method', ( evt ) => {\n\t *\t\t\tevt.stop();\n\t *\t\t}, { priority: 'high' } );\n\t *\n\t *\t\tfoo.method(); // Nothing is logged.\n\t *\n\t *\n\t * Note: we used a high priority listener here to execute this callback before the one which\n\t * calls the orignal method (which used the default priority).\n\t *\n\t * It's also possible to change the return value:\n\t *\n\t *\t\tfoo.on( 'method', ( evt ) => {\n\t *\t\t\tevt.return = 'Foo!';\n\t *\t\t} );\n\t *\n\t *\t\tfoo.method(); // -> 'Foo'\n\t *\n\t * Finally, it's possible to access and modify the parameters:\n\t *\n\t *\t\tmethod( a, b ) {\n\t *\t\t\tconsole.log( `${ a }, ${ b }` );\n\t *\t\t}\n\t *\n\t *\t\t// ...\n\t *\n\t *\t\tfoo.on( 'method', ( evt, args ) => {\n\t *\t\t\targs[ 0 ] = 3;\n\t *\n\t *\t\t\tconsole.log( args[ 1 ] ); // -> 2\n\t *\t\t}, { priority: 'high' } );\n\t *\n\t *\t\tfoo.method( 1, 2 ); // -> '3, 2'\n\t *\n\t * @method #decorate\n\t * @param {String} methodName Name of the method to decorate.\n\t */\n\tdecorate( methodName ) {\n\t\tconst originalMethod = this[ methodName ];\n\n\t\tif ( !originalMethod ) {\n\t\t\t/**\n\t\t\t * Cannot decorate an undefined method.\n\t\t\t *\n\t\t\t * @error observablemixin-cannot-decorate-undefined\n\t\t\t * @param {Object} object The object which method should be decorated.\n\t\t\t * @param {String} methodName Name of the method which does not exist.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'observablemixin-cannot-decorate-undefined: Cannot decorate an undefined method.',\n\t\t\t\t{ object: this, methodName }\n\t\t\t);\n\t\t}\n\n\t\tthis.on( methodName, ( evt, args ) => {\n\t\t\tevt.return = originalMethod.apply( this, args );\n\t\t} );\n\n\t\tthis[ methodName ] = function( ...args ) {\n\t\t\treturn this.fire( methodName, args );\n\t\t};\n\t}\n\n\t/**\n\t * @private\n\t * @member ~ObservableMixin#_boundAttributes\n\t */\n\n\t/**\n\t * @private\n\t * @member ~ObservableMixin#_boundObservables\n\t */\n\n\t/**\n\t * @private\n\t * @member ~ObservableMixin#_bindTo\n\t */\n};\n\nexport default ObservableMixin;\n\n// Init symbol properties needed to for the observable mechanism to work.\n//\n// @private\n// @param {module:utils/observablemixin~ObservableMixin} observable\nfunction initObservable( observable ) {\n\t// Do nothing if already inited.\n\tif ( attributesSymbol in observable ) {\n\t\treturn;\n\t}\n\n\t// The internal hash containing the observable's state.\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, attributesSymbol, {\n\t\tvalue: new Map()\n\t} );\n\n\t// Map containing bindings to external observables. It shares the binding objects\n\t// (`{ observable: A, attr: 'a', to: ... }`) with {@link module:utils/observablemixin~ObservableMixin#_boundAttributes} and\n\t// it is used to observe external observables to update own attributes accordingly.\n\t// See {@link module:utils/observablemixin~ObservableMixin#bind}.\n\t//\n\t//\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n\t//\t\tconsole.log( A._boundObservables );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\tB: {\n\t//\t\t\t\t\tx: Set( [\n\t//\t\t\t\t\t\t{ observable: A, attr: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\t\t\t{ observable: A, attr: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\ty: Set( [\n\t//\t\t\t\t\t\t{ observable: A, attr: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t}\n\t//\t\t\t} )\n\t//\n\t//\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n\t//\t\tconsole.log( A._boundObservables );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\tB: {\n\t//\t\t\t\t\tx: Set( [\n\t//\t\t\t\t\t\t{ observable: A, attr: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\t\t\t{ observable: A, attr: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\ty: Set( [\n\t//\t\t\t\t\t\t{ observable: A, attr: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\tz: Set( [\n\t//\t\t\t\t\t\t{ observable: A, attr: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t},\n\t//\t\t\t\tC: {\n\t//\t\t\t\t\tw: Set( [\n\t//\t\t\t\t\t\t{ observable: A, attr: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t}\n\t//\t\t\t} )\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, boundObservablesSymbol, {\n\t\tvalue: new Map()\n\t} );\n\n\t// Object that stores which attributes of this observable are bound and how. It shares\n\t// the binding objects (`{ observable: A, attr: 'a', to: ... }`) with {@link utils.ObservableMixin#_boundObservables}.\n\t// This data structure is a reverse of {@link utils.ObservableMixin#_boundObservables} and it is helpful for\n\t// {@link utils.ObservableMixin#unbind}.\n\t//\n\t// See {@link utils.ObservableMixin#bind}.\n\t//\n\t//\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n\t//\t\tconsole.log( A._boundAttributes );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\ta: { observable: A, attr: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\tb: { observable: A, attr: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\tc: { observable: A, attr: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t} )\n\t//\n\t//\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n\t//\t\tconsole.log( A._boundAttributes );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\ta: { observable: A, attr: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\tb: { observable: A, attr: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\tc: { observable: A, attr: 'c', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\td: { observable: A, attr: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t} )\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, boundAttributesSymbol, {\n\t\tvalue: new Map()\n\t} );\n}\n\n// A chaining for {@link module:utils/observablemixin~ObservableMixin#bind} providing `.to()` interface.\n//\n// @private\n// @param {...[Observable|String|Function]} args Arguments of the `.to( args )` binding.\nfunction bindTo( ...args ) {\n\tconst parsedArgs = parseBindToArgs( ...args );\n\tconst bindingsKeys = Array.from( this._bindings.keys() );\n\tconst numberOfBindings = bindingsKeys.length;\n\n\t// Eliminate A.bind( 'x' ).to( B, C )\n\tif ( !parsedArgs.callback && parsedArgs.to.length > 1 ) {\n\t\t/**\n\t\t * Binding multiple observables only possible with callback.\n\t\t *\n\t\t * @error observable-bind-no-callback\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-no-callback: Binding multiple observables only possible with callback.' );\n\t}\n\n\t// Eliminate A.bind( 'x', 'y' ).to( B, callback )\n\tif ( numberOfBindings > 1 && parsedArgs.callback ) {\n\t\t/**\n\t\t * Cannot bind multiple attributes and use a callback in one binding.\n\t\t *\n\t\t * @error observable-bind-to-extra-callback\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-extra-callback: Cannot bind multiple attributes and use a callback in one binding.' );\n\t}\n\n\tparsedArgs.to.forEach( to => {\n\t\t// Eliminate A.bind( 'x', 'y' ).to( B, 'a' )\n\t\tif ( to.attrs.length && to.attrs.length !== numberOfBindings ) {\n\t\t\t/**\n\t\t\t * The number of attributes must match.\n\t\t\t *\n\t\t\t * @error observable-bind-to-attrs-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-to-attrs-length: The number of attributes must match.' );\n\t\t}\n\n\t\t// When no to.attrs specified, observing source attributes instead i.e.\n\t\t// A.bind( 'x', 'y' ).to( B ) -> Observe B.x and B.y\n\t\tif ( !to.attrs.length ) {\n\t\t\tto.attrs = this._bindAttrs;\n\t\t}\n\t} );\n\n\tthis._to = parsedArgs.to;\n\n\t// Fill {@link BindChain#_bindings} with callback. When the callback is set there's only one binding.\n\tif ( parsedArgs.callback ) {\n\t\tthis._bindings.get( bindingsKeys[ 0 ] ).callback = parsedArgs.callback;\n\t}\n\n\tattachBindToListeners( this._observable, this._to );\n\n\t// Update observable._boundAttributes and observable._boundObservables.\n\tupdateBindToBound( this );\n\n\t// Set initial values of bound attributes.\n\tthis._bindAttrs.forEach( attrName => {\n\t\tupdateBoundObservableAttr( this._observable, attrName );\n\t} );\n}\n\n// Check if all entries of the array are of `String` type.\n//\n// @private\n// @param {Array} arr An array to be checked.\n// @returns {Boolean}\nfunction isStringArray( arr ) {\n\treturn arr.every( a => typeof a == 'string' );\n}\n\n// Parses and validates {@link Observable#bind}`.to( args )` arguments and returns\n// an object with a parsed structure. For example\n//\n//\t\tA.bind( 'x' ).to( B, 'a', C, 'b', call );\n//\n// becomes\n//\n//\t\t{\n//\t\t\tto: [\n//\t\t\t\t{ observable: B, attrs: [ 'a' ] },\n//\t\t\t\t{ observable: C, attrs: [ 'b' ] },\n//\t\t\t],\n//\t\t\tcallback: call\n// \t\t}\n//\n// @private\n// @param {...*} args Arguments of {@link Observable#bind}`.to( args )`.\n// @returns {Object}\nfunction parseBindToArgs( ...args ) {\n\t// Eliminate A.bind( 'x' ).to()\n\tif ( !args.length ) {\n\t\t/**\n\t\t * Invalid argument syntax in `to()`.\n\t\t *\n\t\t * @error observable-bind-to-parse-error\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-parse-error: Invalid argument syntax in `to()`.' );\n\t}\n\n\tconst parsed = { to: [] };\n\tlet lastObservable;\n\n\tif ( typeof args[ args.length - 1 ] == 'function' ) {\n\t\tparsed.callback = args.pop();\n\t}\n\n\targs.forEach( a => {\n\t\tif ( typeof a == 'string' ) {\n\t\t\tlastObservable.attrs.push( a );\n\t\t} else if ( typeof a == 'object' ) {\n\t\t\tlastObservable = { observable: a, attrs: [] };\n\t\t\tparsed.to.push( lastObservable );\n\t\t} else {\n\t\t\tthrow new CKEditorError( 'observable-bind-to-parse-error: Invalid argument syntax in `to()`.' );\n\t\t}\n\t} );\n\n\treturn parsed;\n}\n\n// Synchronizes {@link module:utils/observablemixin#_boundObservables} with {@link Binding}.\n//\n// @private\n// @param {Binding} binding A binding to store in {@link Observable#_boundObservables}.\n// @param {Observable} toObservable A observable, which is a new component of `binding`.\n// @param {String} toAttrName A name of `toObservable`'s attribute, a new component of the `binding`.\nfunction updateBoundObservables( observable, binding, toObservable, toAttrName ) {\n\tconst boundObservables = observable[ boundObservablesSymbol ];\n\tconst bindingsToObservable = boundObservables.get( toObservable );\n\tconst bindings = bindingsToObservable || {};\n\n\tif ( !bindings[ toAttrName ] ) {\n\t\tbindings[ toAttrName ] = new Set();\n\t}\n\n\t// Pass the binding to a corresponding Set in `observable._boundObservables`.\n\tbindings[ toAttrName ].add( binding );\n\n\tif ( !bindingsToObservable ) {\n\t\tboundObservables.set( toObservable, bindings );\n\t}\n}\n\n// Synchronizes {@link Observable#_boundAttributes} and {@link Observable#_boundObservables}\n// with {@link BindChain}.\n//\n// Assuming the following binding being created\n//\n// \t\tA.bind( 'a', 'b' ).to( B, 'x', 'y' );\n//\n// the following bindings were initialized by {@link Observable#bind} in {@link BindChain#_bindings}:\n//\n// \t\t{\n// \t\t\ta: { observable: A, attr: 'a', to: [] },\n// \t\t\tb: { observable: A, attr: 'b', to: [] },\n// \t\t}\n//\n// Iterate over all bindings in this chain and fill their `to` properties with\n// corresponding to( ... ) arguments (components of the binding), so\n//\n// \t\t{\n// \t\t\ta: { observable: A, attr: 'a', to: [ B, 'x' ] },\n// \t\t\tb: { observable: A, attr: 'b', to: [ B, 'y' ] },\n// \t\t}\n//\n// Then update the structure of {@link Observable#_boundObservables} with updated\n// binding, so it becomes:\n//\n// \t\tMap( {\n// \t\t\tB: {\n// \t\t\t\tx: Set( [\n// \t\t\t\t\t{ observable: A, attr: 'a', to: [ [ B, 'x' ] ] }\n// \t\t\t\t] ),\n// \t\t\t\ty: Set( [\n// \t\t\t\t\t{ observable: A, attr: 'b', to: [ [ B, 'y' ] ] },\n// \t\t\t\t] )\n//\t\t\t}\n// \t\t} )\n//\n// @private\n// @param {BindChain} chain The binding initialized by {@link Observable#bind}.\nfunction updateBindToBound( chain ) {\n\tlet toAttr;\n\n\tchain._bindings.forEach( ( binding, attrName ) => {\n\t\t// Note: For a binding without a callback, this will run only once\n\t\t// like in A.bind( 'x', 'y' ).to( B, 'a', 'b' )\n\t\t// TODO: ES6 destructuring.\n\t\tchain._to.forEach( to => {\n\t\t\ttoAttr = to.attrs[ binding.callback ? 0 : chain._bindAttrs.indexOf( attrName ) ];\n\n\t\t\tbinding.to.push( [ to.observable, toAttr ] );\n\t\t\tupdateBoundObservables( chain._observable, binding, to.observable, toAttr );\n\t\t} );\n\t} );\n}\n\n// Updates an attribute of a {@link Observable} with a value\n// determined by an entry in {@link Observable#_boundAttributes}.\n//\n// @private\n// @param {Observable} observable A observable which attribute is to be updated.\n// @param {String} attrName An attribute to be updated.\nfunction updateBoundObservableAttr( observable, attrName ) {\n\tconst boundAttributes = observable[ boundAttributesSymbol ];\n\tconst binding = boundAttributes.get( attrName );\n\tlet attrValue;\n\n\t// When a binding with callback is created like\n\t//\n\t// \t\tA.bind( 'a' ).to( B, 'b', C, 'c', callback );\n\t//\n\t// collect B.b and C.c, then pass them to callback to set A.a.\n\tif ( binding.callback ) {\n\t\tattrValue = binding.callback.apply( observable, binding.to.map( to => to[ 0 ][ to[ 1 ] ] ) );\n\t} else {\n\t\tattrValue = binding.to[ 0 ];\n\t\tattrValue = attrValue[ 0 ][ attrValue[ 1 ] ];\n\t}\n\n\tif ( observable.hasOwnProperty( attrName ) ) {\n\t\tobservable[ attrName ] = attrValue;\n\t} else {\n\t\tobservable.set( attrName, attrValue );\n\t}\n}\n\n// Starts listening to changes in {@link BindChain._to} observables to update\n// {@link BindChain._observable} {@link BindChain._bindAttrs}. Also sets the\n// initial state of {@link BindChain._observable}.\n//\n// @private\n// @param {BindChain} chain The chain initialized by {@link Observable#bind}.\nfunction attachBindToListeners( observable, toBindings ) {\n\ttoBindings.forEach( to => {\n\t\tconst boundObservables = observable[ boundObservablesSymbol ];\n\t\tlet bindings;\n\n\t\t// If there's already a chain between the observables (`observable` listens to\n\t\t// `to.observable`), there's no need to create another `change` event listener.\n\t\tif ( !boundObservables.get( to.observable ) ) {\n\t\t\tobservable.listenTo( to.observable, 'change', ( evt, attrName ) => {\n\t\t\t\tbindings = boundObservables.get( to.observable )[ attrName ];\n\n\t\t\t\t// Note: to.observable will fire for any attribute change, react\n\t\t\t\t// to changes of attributes which are bound only.\n\t\t\t\tif ( bindings ) {\n\t\t\t\t\tbindings.forEach( binding => {\n\t\t\t\t\t\tupdateBoundObservableAttr( observable, binding.attr );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n}\n\nextend( ObservableMixin, EmitterMixin );\n\n/**\n * Fired when an attribute changed value.\n *\n *\t\tobservable.set( 'prop', 1 );\n *\n *\t\tobservable.on( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `${ propertyName } has changed from ${ oldValue } to ${ newValue }` );\n *\t\t} )\n *\n *\t\tobservable.prop = 2; // -> 'prop has changed from 1 to 2'\n *\n * @event module:utils/observablemixin~ObservableMixin#change:{attribute}\n * @param {String} name The attribute name.\n * @param {*} value The new attribute value.\n * @param {*} oldValue The previous attribute value.\n */\n\n/**\n * Interface representing classes which mix in {@link module:utils/observablemixin~ObservableMixin}.\n *\n * @interface Observable\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/observablemixin.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/objecttomap\n */\n\n/**\n * Transforms object to map.\n *\n *\t\tconst map = objectToMap( { 'foo': 1, 'bar': 2 } );\n *\t\tmap.get( 'foo' ); // 1\n *\n * @param {Object} obj Object to transform.\n * @returns {Map} Map created from object.\n */\nexport default function objectToMap( obj ) {\n\tconst map = new Map();\n\n\tfor ( const key in obj ) {\n\t\tmap.set( key, obj[ key ] );\n\t}\n\n\treturn map;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/objecttomap.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/tomap\n */\n\nimport isPlainObject from './lib/lodash/isPlainObject';\nimport objectToMap from './objecttomap';\n\n/**\n * Transforms object or iterable to map. Iterable needs to be in the format acceptable by the `Map` constructor.\n *\n *\t\tmap = toMap( { 'foo': 1, 'bar': 2 } );\n *\t\tmap = toMap( [ [ 'foo', 1 ], [ 'bar', 2 ] ] );\n *\t\tmap = toMap( anotherMap );\n *\n * @param {Object|Iterable} data Object or iterable to transform.\n * @returns {Map} Map created from data.\n */\nexport default function toMap( data ) {\n\tif ( isPlainObject( data ) ) {\n\t\treturn objectToMap( data );\n\t} else {\n\t\treturn new Map( data );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/tomap.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/node\n */\n\nimport toMap from '@ckeditor/ckeditor5-utils/src/tomap';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\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/document~Document#batch Batch API}.\n *\n * Changes done by `Node` methods, like {@link module:engine/model/element~Element#insertChildren insertChildren} or\n * {@link module:engine/model/node~Node#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~Document 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/batch~Batch#insert inserting} that node to the model tree.\n *\n * Be aware that using {@link module:engine/model/batch~Batch#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~Element element node}, adding and removing children also counts as changing a node and\n * follows same rules.\n */\nexport default class Node {\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 * @abstract\n\t * @param {Object} [attrs] Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */\n\tconstructor( attrs ) {\n\t\t/**\n\t\t * Parent of this node. It could be {@link module:engine/model/element~Element}\n\t\t * or {@link module:engine/model/documentfragment~DocumentFragment}.\n\t\t * Equals to `null` if the node has no parent.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t\t */\n\t\tthis.parent = null;\n\n\t\t/**\n\t\t * Attributes set on this node.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/model/node~Node#_attrs\n\t\t */\n\t\tthis._attrs = toMap( attrs );\n\t}\n\n\t/**\n\t * Index of this node in it's parent 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 model tree got broken.\n\t *\n\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget index() {\n\t\tlet pos;\n\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( ( pos = this.parent.getChildIndex( this ) ) === null ) {\n\t\t\tthrow new CKEditorError( 'model-node-not-found-in-parent: The node\\'s parent does not contain this node.' );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Offset at which this node starts in it's parent. It is equal to the sum of {@link #offsetSize offsetSize}\n\t * of all it's previous siblings. Equals to `null` if 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 model tree got broken.\n\t *\n\t * @readonly\n\t * @type {Number|Null}\n\t */\n\tget startOffset() {\n\t\tlet pos;\n\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( ( pos = this.parent.getChildStartOffset( this ) ) === null ) {\n\t\t\tthrow new CKEditorError( 'model-node-not-found-in-parent: The node\\'s parent does not contain this node.' );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Offset size of this node. Represents how much \"offset space\" is occupied by the node in it's parent.\n\t * It is important for {@link module:engine/model/position~Position position}. When node has `offsetSize` greater than `1`, position\n\t * can be placed between that node start and end. `offsetSize` greater than `1` is for nodes that represents more\n\t * than one entity, i.e. {@link module:engine/model/text~Text text node}.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget offsetSize() {\n\t\treturn 1;\n\t}\n\n\t/**\n\t * Offset at which this node ends in it's parent. It is equal to the sum of this node's\n\t * {@link module:engine/model/node~Node#startOffset start offset} and {@link #offsetSize offset size}.\n\t * Equals to `null` if the node has no parent.\n\t *\n\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget endOffset() {\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.startOffset + this.offsetSize;\n\t}\n\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\t * @readonly\n\t * @type {module:engine/model/node~Node|null}\n\t */\n\tget nextSibling() {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent.getChild( index + 1 ) ) || null;\n\t}\n\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\t * @readonly\n\t * @type {module:engine/model/node~Node|null}\n\t */\n\tget previousSibling() {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent.getChild( index - 1 ) ) || null;\n\t}\n\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~DocumentFragment}, it's `root` is equal to that `DocumentFragment`.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/node~Node|module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\tlet root = this; // eslint-disable-line consistent-this\n\n\t\twhile ( root.parent ) {\n\t\t\troot = root.parent;\n\t\t}\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * {@link module:engine/model/document~Document Document} that owns this node or `null` if the node has no parent or is inside\n\t * a {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/document~Document|null}\n\t */\n\tget document() {\n\t\t// This is a top element of a sub-tree.\n\t\tif ( this.root == this ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Root may be `DocumentFragment` which does not have document property.\n\t\treturn this.root.document || null;\n\t}\n\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 * @returns {module:engine/model/node~Node} Node with same attributes as this node.\n\t */\n\tclone() {\n\t\treturn new Node( this._attrs );\n\t}\n\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~Node#root root}, down to this node's starting offset. The path can be used to\n\t * create {@link module:engine/model/position~Position Position} instance.\n\t *\n\t *\t\tconst abc = new Text( 'abc' );\n\t *\t\tconst foo = new Text( 'foo' );\n\t *\t\tconst h1 = new Element( 'h1', null, new Text( 'header' ) );\n\t *\t\tconst p = new Element( 'p', null, [ abc, foo ] );\n\t *\t\tconst div = new Element( 'div', null, [ h1, p ] );\n\t *\t\tfoo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t *\t\th1.getPath(); // Returns [ 0 ].\n\t *\t\tdiv.getPath(); // Returns [].\n\t *\n\t * @returns {Array.<Number>} The path.\n\t */\n\tgetPath() {\n\t\tconst path = [];\n\t\tlet node = this; // eslint-disable-line consistent-this\n\n\t\twhile ( node.parent ) {\n\t\t\tpath.unshift( node.startOffset );\n\t\t\tnode = node.parent;\n\t\t}\n\n\t\treturn path;\n\t}\n\n\t/**\n\t * Returns ancestors array of this node.\n\t *\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` this node will be also included in parent's array.\n\t * @param {Boolean} [options.parentFirst=false] 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} Array with ancestors.\n\t */\n\tgetAncestors( options = { includeSelf: false, parentFirst: false } ) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both nodes.\n\t *\n\t * @param {module:engine/model/node~Node} node The second node.\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] 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 * @returns {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor( node, options = {} ) {\n\t\tconst ancestorsA = this.getAncestors( options );\n\t\tconst ancestorsB = node.getAncestors( options );\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Removes this node from it's parent.\n\t */\n\tremove() {\n\t\tthis.parent.removeChildren( this.index );\n\t}\n\n\t/**\n\t * Checks if the node has an attribute with given key.\n\t *\n\t * @param {String} key Key of attribute to check.\n\t * @returns {Boolean} `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\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 {String} 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\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\t * @returns {Iterable.<*>}\n\t */\n\tgetAttributes() {\n\t\treturn this._attrs.entries();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attribute keys.\n\t *\n\t * @returns {Iterator.<String>}\n\t */\n\tgetAttributeKeys() {\n\t\treturn this._attrs.keys();\n\t}\n\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 * @param {String} key Key of attribute to set.\n\t * @param {*} value Attribute value.\n\t */\n\tsetAttribute( key, value ) {\n\t\tthis._attrs.set( key, value );\n\t}\n\n\t/**\n\t * Removes all attributes from the node and sets given attributes.\n\t *\n\t * @param {Object} [attrs] Attributes to set. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */\n\tsetAttributesTo( attrs ) {\n\t\tthis._attrs = toMap( attrs );\n\t}\n\n\t/**\n\t * Removes an attribute with given key from the node.\n\t *\n\t * @param {String} key Key of attribute to remove.\n\t * @returns {Boolean} `true` if the attribute was set on the element, `false` otherwise.\n\t */\n\tremoveAttribute( key ) {\n\t\treturn this._attrs.delete( key );\n\t}\n\n\t/**\n\t * Removes all attributes from the node.\n\t */\n\tclearAttributes() {\n\t\tthis._attrs.clear();\n\t}\n\n\t/**\n\t * Converts `Node` to plain object and returns it.\n\t *\n\t * @returns {Object} `Node` converted to plain object.\n\t */\n\ttoJSON() {\n\t\tconst json = {};\n\n\t\tif ( this._attrs.size ) {\n\t\t\tjson.attributes = [ ...this._attrs ];\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Checks whether given model tree object is of given type.\n\t *\n\t * This method is useful when processing model tree objects that are of unknown type. For example, a function\n\t * may return {@link module:engine/model/documentfragment~DocumentFragment} or {@link module:engine/model/node~Node}\n\t * that can be either text node or element. This method can be used to check what kind of object is returned.\n\t *\n\t *\t\tobj.is( 'node' ); // true for any node, false for document fragment\n\t *\t\tobj.is( 'documentFragment' ); // true for document fragment, false for any node\n\t *\t\tobj.is( 'element' ); // true for any element, false for text node or document fragment\n\t *\t\tobj.is( 'element', 'paragraph' ); // true only for element which name is 'paragraph'\n\t *\t\tobj.is( 'paragraph' ); // shortcut for obj.is( 'element', 'paragraph' )\n\t *\t\tobj.is( 'text' ); // true for text node, false for element and document fragment\n\t *\t\tobj.is( 'textProxy' ); // true for text proxy object\n\t *\n\t * @method #is\n\t * @param {'element'|'rootElement'|'text'|'textProxy'|'documentFragment'} type\n\t * @returns {Boolean}\n\t */\n}\n\n/**\n * The node's parent does not contain this node.\n *\n * This error may be thrown from corrupted trees.\n *\n * @error model-node-not-found-in-parent\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/node.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/isiterable\n */\n\n/**\n * Checks if value implements iterator interface.\n *\n * @param {*} value The value to check.\n * @returns {Boolean} True if value implements iterator interface.\n */\nexport default function isIterable( value ) {\n\treturn !!( value && value[ Symbol.iterator ] );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/isiterable.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/element\n */\n\nimport Node from './node';\nimport NodeList from './nodelist';\nimport Text from './text';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * Model element. Type of {@link module:engine/model/node~Node node} that has a {@link module:engine/model/element~Element#name name} and\n * {@link module:engine/model/element~Element#getChildren child nodes}.\n *\n * **Important**: see {@link module:engine/model/node~Node} to read about restrictions using `Element` and `Node` API.\n */\nexport default class Element extends Node {\n\t/**\n\t * Creates a model element.\n\t *\n\t * @param {String} name Element's name.\n\t * @param {Object} [attrs] Element's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} [children]\n\t * One or more nodes to be inserted as children of created element.\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper( attrs );\n\n\t\t/**\n\t\t * Element name.\n\t\t *\n\t\t * @member {String} module:engine/model/element~Element#name\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * List of children nodes.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/nodelist~NodeList} module:engine/model/element~Element#_children\n\t\t */\n\t\tthis._children = new NodeList();\n\n\t\tif ( children ) {\n\t\t\tthis.insertChildren( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Number of this element's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Sum of {module:engine/model/node~Node#offsetSize offset sizes} of all of this element's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget maxOffset() {\n\t\treturn this._children.maxOffset;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this element, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Checks whether given model tree object is of given type.\n\t *\n\t *\t\tobj.name; // 'listItem'\n\t *\t\tobj instanceof Element; // true\n\t *\n\t *\t\tobj.is( 'element' ); // true\n\t *\t\tobj.is( 'listItem' ); // true\n\t *\t\tobj.is( 'element', 'listItem' ); // true\n\t *\t\tobj.is( 'text' ); // false\n\t *\t\tobj.is( 'element', 'image' ); // false\n\t *\n\t * Read more in {@link module:engine/model/node~Node#is}.\n\t *\n\t * @param {String} type Type to check when `name` parameter is present.\n\t * Otherwise, it acts like the `name` parameter.\n\t * @param {String} [name] Element name.\n\t * @returns {Boolean}\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'element' || type == this.name;\n\t\t} else {\n\t\t\treturn type == 'element' && name == this.name;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the child at the given index.\n\t *\n\t * @param {Number} index Index of child.\n\t * @returns {module:engine/model/node~Node} Child node.\n\t */\n\tgetChild( index ) {\n\t\treturn this._children.getNode( index );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all of this element's children.\n\t *\n\t * @returns {Iterable.<module:engine/model/node~Node>}\n\t */\n\tgetChildren() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\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 {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number} Child node's index in this element.\n\t */\n\tgetChildIndex( node ) {\n\t\treturn this._children.getNodeIndex( node );\n\t}\n\n\t/**\n\t * Returns the starting offset of given child. Starting offset is equal to the sum of\n\t * {module:engine/model/node~Node#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 {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number} Child node's starting offset.\n\t */\n\tgetChildStartOffset( node ) {\n\t\treturn this._children.getNodeStartOffset( node );\n\t}\n\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 removed.\n\t *\n\t * @param {Boolean} [deep=false] 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\tclone( deep = false ) {\n\t\tconst children = deep ? Array.from( this._children ).map( node => node.clone( true ) ) : null;\n\n\t\treturn new Element( this.name, this.getAttributes(), children );\n\t}\n\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~Element#getChildIndex index after last child}.\n\t *\n\t *\t\tconst textNode = new Text( 'foo' );\n\t *\t\tconst pElement = new Element( 'p' );\n\t *\t\tconst divElement = new Element( [ textNode, pElement ] );\n\t *\t\tdivElement.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t *\t\tdivElement.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t *\t\tdivElement.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t *\t\tdivElement.offsetToIndex( 2 ); // Returns 0.\n\t *\t\tdivElement.offsetToIndex( 3 ); // Returns 1.\n\t *\t\tdivElement.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t *\n\t * @param {Number} offset Offset to look for.\n\t * @returns {Number}\n\t */\n\toffsetToIndex( offset ) {\n\t\treturn this._children.offsetToIndex( offset );\n\t}\n\n\t/**\n\t * {@link module:engine/model/element~Element#insertChildren Inserts} one or more nodes at the end of this element.\n\t *\n\t * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} nodes Nodes to be inserted.\n\t */\n\tappendChildren( nodes ) {\n\t\tthis.insertChildren( this.childCount, nodes );\n\t}\n\n\t/**\n\t * Inserts one or more nodes at the given index and sets {@link module:engine/model/node~Node#parent parent} of these nodes\n\t * to this element.\n\t *\n\t * @param {Number} index Index at which nodes should be inserted.\n\t * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} nodes Nodes to be inserted.\n\t */\n\tinsertChildren( index, nodes ) {\n\t\tnodes = normalize( nodes );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode.remove();\n\t\t\t}\n\n\t\t\tnode.parent = this;\n\t\t}\n\n\t\tthis._children.insertNodes( index, nodes );\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index and sets\n\t * {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.\n\t *\n\t * @param {Number} index Index of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/model/node~Node>} Array containing removed nodes.\n\t */\n\tremoveChildren( index, howMany = 1 ) {\n\t\tconst nodes = this._children.removeNodes( index, howMany );\n\n\t\tfor ( const node of nodes ) {\n\t\t\tnode.parent = null;\n\t\t}\n\n\t\treturn nodes;\n\t}\n\n\t/**\n\t * Returns a descendant node by its path relative to this element.\n\t *\n\t *\t\t// <this>a<b>c</b></this>\n\t *\t\tthis.getNodeByPath( [ 0 ] ); // -> \"a\"\n\t *\t\tthis.getNodeByPath( [ 1 ] ); // -> <b>\n\t *\t\tthis.getNodeByPath( [ 1, 0 ] ); // -> \"c\"\n\t *\n\t * @param {Array.<Number>} relativePath Path of the node to find, relative to this element.\n\t * @returns {module:engine/model/node~Node}\n\t */\n\tgetNodeByPath( relativePath ) {\n\t\tlet node = this; // eslint-disable-line consistent-this\n\n\t\tfor ( const index of relativePath ) {\n\t\t\tnode = node.getChild( node.offsetToIndex( index ) );\n\t\t}\n\n\t\treturn node;\n\t}\n\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 {Object} `Element` instance converted to plain object.\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.name = this.name;\n\n\t\tif ( this._children.length > 0 ) {\n\t\t\tjson.children = [];\n\n\t\t\tfor ( const node of this._children ) {\n\t\t\t\tjson.children.push( node.toJSON() );\n\t\t\t}\n\t\t}\n\n\t\treturn json;\n\t}\n\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 {Object} json Plain object to be converted to `Element`.\n\t * @returns {module:engine/model/element~Element} `Element` instance created using given plain object.\n\t */\n\tstatic fromJSON( json ) {\n\t\tlet children = null;\n\n\t\tif ( json.children ) {\n\t\t\tchildren = [];\n\n\t\t\tfor ( const child of json.children ) {\n\t\t\t\tif ( child.name ) {\n\t\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn new Element( json.name, json.attributes, children );\n\t}\n}\n\n// Converts strings to Text and non-iterables to arrays.\n//\n// @param {String|module:engine/model/node~Node|Iterable.<String|module:engine/model/node~Node>}\n// @return {Iterable.<module:engine/model/node~Node>}\nfunction normalize( nodes ) {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\treturn typeof node == 'string' ? new Text( node ) : node;\n\t\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/element.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/treewalker\n */\n\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport Element from './element';\nimport Position from './position';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */\nexport default class TreeWalker {\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 * @constructor\n\t * @param {Object} [options={}] Object with configuration.\n\t * @param {'forward'|'backward'} [options.direction='forward'] Walking direction.\n\t * @param {module:engine/model/range~Range} [options.boundaries=null] Range to define boundaries of the iterator.\n\t * @param {module:engine/model/position~Position} [options.startPosition] Starting position.\n\t * @param {Boolean} [options.singleCharacters=false] Flag indicating whether all consecutive characters with the same attributes\n\t * should be returned one by one as multiple {@link module:engine/model/textproxy~TextProxy} (`true`) objects or as one\n\t * {@link module:engine/model/textproxy~TextProxy} (`false`).\n\t * @param {Boolean} [options.shallow=false] Flag indicating whether iterator should enter elements or not. If the\n\t * iterator is shallow child nodes of any iterated node will not be returned along with `elementEnd` tag.\n\t * @param {Boolean} [options.ignoreElementEnd=false] Flag indicating whether iterator should ignore `elementEnd`\n\t * tags. If the option is true walker will not return a parent node of start position. If this option is `true`\n\t * each {@link module:engine/model/element~Element} will be returned once, while if the option is `false` they might be returned\n\t * twice: for `'elementStart'` and `'elementEnd'`.\n\t */\n\tconstructor( options = {} ) {\n\t\tif ( !options.boundaries && !options.startPosition ) {\n\t\t\t/**\n\t\t\t * Neither boundaries nor starting position of a `TreeWalker` have been defined.\n\t\t\t *\n\t\t\t * @error model-tree-walker-no-start-position\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-tree-walker-no-start-position: Neither boundaries nor starting position have been defined.' );\n\t\t}\n\n\t\tconst direction = options.direction || 'forward';\n\n\t\tif ( direction != 'forward' && direction != 'backward' ) {\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-tree-walker-unknown-direction: Only `backward` and `forward` direction allowed.',\n\t\t\t\t{ direction }\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Walking direction. Defaults `'forward'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'backward'|'forward'} module:engine/model/treewalker~TreeWalker#direction\n\t\t */\n\t\tthis.direction = direction;\n\n\t\t/**\n\t\t * Iterator boundaries.\n\t\t *\n\t\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t\t * on the start of boundary, then `{ done: true }` is returned.\n\t\t *\n\t\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/range~Range} module:engine/model/treewalker~TreeWalker#boundaries\n\t\t */\n\t\tthis.boundaries = options.boundaries || null;\n\n\t\t/**\n\t\t * Iterator position. This is always static position, even if the initial position was a\n\t\t * {@link module:engine/model/liveposition~LivePosition live position}. If start position is not defined then position depends\n\t\t * on {@link #direction}. If direction is `'forward'` position starts form the beginning, when direction\n\t\t * is `'backward'` position starts from the end.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/position~Position} module:engine/model/treewalker~TreeWalker#position\n\t\t */\n\t\tif ( options.startPosition ) {\n\t\t\tthis.position = Position.createFromPosition( options.startPosition );\n\t\t} else {\n\t\t\tthis.position = Position.createFromPosition( this.boundaries[ this.direction == 'backward' ? 'end' : 'start' ] );\n\t\t}\n\n\t\t/**\n\t\t * Flag indicating whether all consecutive characters with the same attributes should be\n\t\t * returned as one {@link module:engine/model/textproxy~TextProxy} (`true`) or one by one (`false`).\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/model/treewalker~TreeWalker#singleCharacters\n\t\t */\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t\t * iterated node will not be returned along with `elementEnd` tag.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/model/treewalker~TreeWalker#shallow\n\t\t */\n\t\tthis.shallow = !!options.shallow;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should ignore `elementEnd` tags. If the option is true walker will not\n\t\t * return a parent node of the start position. If this option is `true` each {@link module:engine/model/element~Element} will\n\t\t * be returned once, while if the option is `false` they might be returned twice:\n\t\t * for `'elementStart'` and `'elementEnd'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/model/treewalker~TreeWalker#ignoreElementEnd\n\t\t */\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\n\t\t/**\n\t\t * Start boundary cached for optimization purposes.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/element~Element} module:engine/model/treewalker~TreeWalker#_boundaryStartParent\n\t\t */\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\n\t\t/**\n\t\t * End boundary cached for optimization purposes.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/element~Element} module:engine/model/treewalker~TreeWalker#_boundaryEndParent\n\t\t */\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\n\t\t/**\n\t\t * Parent of the most recently visited node. Cached for optimization purposes.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment}\n\t\t * module:engine/model/treewalker~TreeWalker#_visitedParent\n\t\t */\n\t\tthis._visitedParent = this.position.parent;\n\t}\n\n\t/**\n\t * Iterator interface.\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this;\n\t}\n\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 * \t\twalker.skip( value => value.type == 'text' ); // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t * \t\twalker.skip( () => true ); // Move the position to the end: <paragraph>[]foo</paragraph> -> <paragraph>foo</paragraph>[]\n\t * \t\twalker.skip( () => false ); // Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/model/treewalker~TreeWalkerValue} 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\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\t\t\tprevVisitedParent = this._visitedParent;\n\n\t\t\t( { done, value } = this.next() );\n\t\t} while ( !done && skip( value ) );\n\n\t\tif ( !done ) {\n\t\t\tthis.position = prevPosition;\n\t\t\tthis._visitedParent = prevVisitedParent;\n\t\t}\n\t}\n\n\t/**\n\t * Iterator interface method.\n\t * Detects walking direction and makes step forward or backward.\n\t *\n\t * @returns {Object} Object implementing iterator interface, returning information about taken step.\n\t */\n\tnext() {\n\t\tif ( this.direction == 'forward' ) {\n\t\t\treturn this._next();\n\t\t} else {\n\t\t\treturn this._previous();\n\t\t}\n\t}\n\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 * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done True if iterator is done.\n\t * @returns {module:engine/model/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_next() {\n\t\tconst previousPosition = this.position;\n\t\tconst position = Position.createFromPosition( this.position );\n\t\tconst parent = this._visitedParent;\n\n\t\t// We are at the end of the root.\n\t\tif ( parent.parent === null && position.offset === parent.maxOffset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\tconst node = position.textNode ? position.textNode : position.nodeAfter;\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\t// Manual operations on path internals for optimization purposes. Here and in the rest of the method.\n\t\t\t\tposition.path.push( 0 );\n\t\t\t\tthis._visitedParent = node;\n\t\t\t} else {\n\t\t\t\tposition.offset++;\n\t\t\t}\n\n\t\t\tthis.position = position;\n\n\t\t\treturn formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t} else if ( node instanceof Text ) {\n\t\t\tlet charactersCount;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tcharactersCount = 1;\n\t\t\t} else {\n\t\t\t\tlet offset = node.endOffset;\n\n\t\t\t\tif ( this._boundaryEndParent == parent && this.boundaries.end.offset < offset ) {\n\t\t\t\t\toffset = this.boundaries.end.offset;\n\t\t\t\t}\n\n\t\t\t\tcharactersCount = offset - position.offset;\n\t\t\t}\n\n\t\t\tconst offsetInTextNode = position.offset - node.startOffset;\n\t\t\tconst item = new TextProxy( node, offsetInTextNode, charactersCount );\n\n\t\t\tposition.offset += charactersCount;\n\t\t\tthis.position = position;\n\n\t\t\treturn formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the end of current `parent`.\n\t\t\tposition.path.pop();\n\t\t\tposition.offset++;\n\t\t\tthis.position = position;\n\t\t\tthis._visitedParent = parent.parent;\n\n\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\treturn this._next();\n\t\t\t} else {\n\t\t\t\treturn formatReturnValue( 'elementEnd', parent, previousPosition, position );\n\t\t\t}\n\t\t}\n\t}\n\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 * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done True if iterator is done.\n\t * @returns {module:engine/model/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_previous() {\n\t\tconst previousPosition = this.position;\n\t\tconst position = Position.createFromPosition( this.position );\n\t\tconst parent = this._visitedParent;\n\n\t\t// We are at the beginning of the root.\n\t\tif ( parent.parent === null && position.offset === 0 ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Get node just before current position\n\t\tconst node = position.textNode ? position.textNode : position.nodeBefore;\n\n\t\tif ( node instanceof Element ) {\n\t\t\tposition.offset--;\n\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition.path.push( node.maxOffset );\n\t\t\t\tthis.position = position;\n\t\t\t\tthis._visitedParent = node;\n\n\t\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\t\treturn this._previous();\n\t\t\t\t} else {\n\t\t\t\t\treturn formatReturnValue( 'elementEnd', node, previousPosition, position );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t\t}\n\t\t} else if ( node instanceof Text ) {\n\t\t\tlet charactersCount;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tcharactersCount = 1;\n\t\t\t} else {\n\t\t\t\tlet offset = node.startOffset;\n\n\t\t\t\tif ( this._boundaryStartParent == parent && this.boundaries.start.offset > offset ) {\n\t\t\t\t\toffset = this.boundaries.start.offset;\n\t\t\t\t}\n\n\t\t\t\tcharactersCount = position.offset - offset;\n\t\t\t}\n\n\t\t\tconst offsetInTextNode = position.offset - node.startOffset;\n\t\t\tconst item = new TextProxy( node, offsetInTextNode - charactersCount, charactersCount );\n\n\t\t\tposition.offset -= charactersCount;\n\t\t\tthis.position = position;\n\n\t\t\treturn formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the beginning of current `parent`.\n\t\t\tposition.path.pop();\n\t\t\tthis.position = position;\n\t\t\tthis._visitedParent = parent.parent;\n\n\t\t\treturn formatReturnValue( 'elementStart', parent, previousPosition, position, 1 );\n\t\t}\n\t}\n}\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 * Type of the step made by {@link module:engine/model/treewalker~TreeWalker}.\n * Possible values: `'elementStart'` if walker is at the beginning of a node, `'elementEnd'` if walker is at the end of node,\n * `'character'` if walker traversed over a character, or `'text'` if walker traversed over multiple characters (available in\n * character merging mode, see {@link module:engine/model/treewalker~TreeWalker#constructor}).\n *\n * @typedef {'elementStart'|'elementEnd'|'character'|'text'} module:engine/model/treewalker~TreeWalkerValueType\n */\n\n/**\n * Object returned by {@link module:engine/model/treewalker~TreeWalker} when traversing tree model.\n *\n * @typedef {Object} module:engine/model/treewalker~TreeWalkerValue\n * @property {module:engine/model/treewalker~TreeWalkerValueType} type\n * @property {module:engine/model/item~Item} item Item between old and new positions of {@link module:engine/model/treewalker~TreeWalker}.\n * @property {module:engine/model/position~Position} previousPosition Previous position of the iterator.\n * * Forward iteration: For `'elementEnd'` it is the last position inside the element. For all other types it is the\n * position before the item. Note that it is more efficient to use this position then calculate the position before\n * the node using {@link module:engine/model/position~Position.createBefore}. It is also more efficient to get the\n * position after node by shifting `previousPosition` by `length`, using {@link module:engine/model/position~Position#getShiftedBy},\n * then calculate the position using {@link module:engine/model/position~Position.createAfter}.\n * * Backward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after item.\n * @property {module:engine/model/position~Position} nextPosition Next position of the iterator.\n * * Forward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after the item.\n * * Backward iteration: For `'elementEnd'` it is last position inside element. For all other types it is the position\n * before the item.\n * @property {Number} [length] Length of the item. For `'elementStart'` and `'character'` it is 1. For `'text'` it is\n * the length of the text. For `'elementEnd'` it is undefined.\n */\n\n/**\n * Tree walking directions.\n *\n * @typedef {'forward'|'backward'} module:engine/view/treewalker~TreeWalkerDirection\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/treewalker.js\n// module id = null\n// module chunks = ","/**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\nfunction last(array) {\n var length = array ? array.length : 0;\n return length ? array[length - 1] : undefined;\n}\n\nexport default last;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/last.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/comparearrays\n */\n\n/**\n * Compares how given arrays relate to each other. One array can be: same as another array, prefix of another array\n * or completely different. If arrays are different, first index at which they differ is returned. Otherwise,\n * a flag specifying the relation is returned. Flags are negative numbers, so whenever a number >= 0 is returned\n * it means that arrays differ.\n *\n *\t\tcompareArrays( [ 0, 2 ], [ 0, 2 ] );\t\t// 'same'\n *\t\tcompareArrays( [ 0, 2 ], [ 0, 2, 1 ] );\t\t// 'prefix'\n *\t\tcompareArrays( [ 0, 2 ], [ 0 ] );\t\t\t// 'extension'\n *\t\tcompareArrays( [ 0, 2 ], [ 1, 2 ] );\t\t// 0\n *\t\tcompareArrays( [ 0, 2 ], [ 0, 1 ] );\t\t// 1\n *\n * @param {Array} a Array that is compared.\n * @param {Array} b Array to compare with.\n * @returns {module:utils/comparearrays~ArrayRelation} How array `a` is related to `b`.\n */\nexport default function compareArrays( a, b ) {\n\tconst minLen = Math.min( a.length, b.length );\n\n\tfor ( let i = 0; i < minLen; i++ ) {\n\t\tif ( a[ i ] != b[ i ] ) {\n\t\t\t// The arrays are different.\n\t\t\treturn i;\n\t\t}\n\t}\n\n\t// Both arrays were same at all points.\n\tif ( a.length == b.length ) {\n\t\t// If their length is also same, they are the same.\n\t\treturn 'same';\n\t} else if ( a.length < b.length ) {\n\t\t// Compared array is shorter so it is a prefix of the other array.\n\t\treturn 'prefix';\n\t} else {\n\t\t// Compared array is longer so it is an extension of the other array.\n\t\treturn 'extension';\n\t}\n}\n\n/**\n * @typedef {'extension'|'same'|'prefix'} module:utils/comparearrays~ArrayRelation\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/comparearrays.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/position\n */\n\nimport TreeWalker from './treewalker';\nimport last from '@ckeditor/ckeditor5-utils/src/lib/lodash/last';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Text from './text';\n\n/**\n * Represents a position in the model tree.\n *\n * **Note:** Position is based on offsets, not indexes. This means that position in element containing two text nodes\n * with data `foo` and `bar`, position between them has offset `3`, not `1`.\n * See {@link module:engine/model/position~Position#path} for more.\n *\n * Since position in a model is represented by a {@link module:engine/model/position~Position#root position root} and\n * {@link module:engine/model/position~Position#path position path} it is possible to create positions placed in non-existing elements.\n * This requirement is important for {@link module:engine/model/operation/transform~transform operational transformation}.\n *\n * Also, {@link module:engine/model/operation/operation~Operation operations}\n * kept in {@link module:engine/model/document~Document#history document history}\n * are storing positions (and ranges) which were correct when those operations were applied, but may not be correct\n * after document got changed.\n *\n * When changes are applied to model, it may also happen that {@link module:engine/model/position~Position#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~Position#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 */\nexport default class Position {\n\t/**\n\t * Creates a position.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} root Root of the position.\n\t * @param {Array.<Number>} path Position path. See {@link module:engine/model/position~Position#path}.\n\t */\n\tconstructor( root, path ) {\n\t\tif ( !root.is( 'element' ) && !root.is( 'documentFragment' ) ) {\n\t\t\t/**\n\t\t\t * Position root is invalid.\n\t\t\t *\n\t\t\t * Positions can only be anchored in elements or document fragments.\n\t\t\t *\n\t\t\t * @error model-position-root-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-position-root-invalid: Position root invalid.' );\n\t\t}\n\n\t\tif ( !( path instanceof Array ) || path.length === 0 ) {\n\t\t\t/**\n\t\t\t * Position path must be an array with at least one item.\n\t\t\t *\n\t\t\t * @error model-position-path-incorrect\n\t\t\t * @param path\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-position-path-incorrect: Position path must be an array with at least one item.', { path } );\n\t\t}\n\n\t\t// Normalize the root and path (if element was passed).\n\t\tpath = root.getPath().concat( path );\n\t\troot = root.root;\n\n\t\t/**\n\t\t * Root of the position path.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment}\n\t\t * module:engine/model/position~Position#root\n\t\t */\n\t\tthis.root = root;\n\n\t\t/**\n\t\t * Position of the node in the tree. **Path contains offsets, not indexes.**\n\t\t *\n\t\t * Position can be placed before, after or in a {@link module:engine/model/node~Node node} if that node has\n\t\t * {@link module:engine/model/node~Node#offsetSize} greater than `1`. Items in position path are\n\t\t * {@link module:engine/model/node~Node#startOffset starting offsets} of position ancestors, starting from direct root children,\n\t\t * down to the position offset in it's parent.\n\t\t *\n\t\t *\t\t ROOT\n\t\t *\t\t |- P before: [ 0 ] after: [ 1 ]\n\t\t *\t\t |- UL before: [ 1 ] after: [ 2 ]\n\t\t *\t\t |- LI before: [ 1, 0 ] after: [ 1, 1 ]\n\t\t *\t\t | |- foo before: [ 1, 0, 0 ] after: [ 1, 0, 3 ]\n\t\t *\t\t |- LI before: [ 1, 1 ] after: [ 1, 2 ]\n\t\t *\t\t |- bar before: [ 1, 1, 0 ] after: [ 1, 1, 3 ]\n\t\t *\n\t\t * `foo` and `bar` are representing {@link module:engine/model/text~Text text nodes}. Since text nodes has offset size\n\t\t * greater than `1` you can place position offset between their start and end:\n\t\t *\n\t\t *\t\t ROOT\n\t\t *\t\t |- P\n\t\t *\t\t |- UL\n\t\t *\t\t |- LI\n\t\t *\t\t | |- f^o|o ^ has path: [ 1, 0, 1 ] | has path: [ 1, 0, 2 ]\n\t\t *\t\t |- LI\n\t\t *\t\t |- b^a|r ^ has path: [ 1, 1, 1 ] | has path: [ 1, 1, 2 ]\n\t\t *\n\t\t * @member {Array.<Number>} module:engine/model/position~Position#path\n\t\t */\n\t\tthis.path = path;\n\t}\n\n\t/**\n\t * Offset at which this position is located in its {@link module:engine/model/position~Position#parent parent}. It is equal\n\t * to the last item in position {@link module:engine/model/position~Position#path path}.\n\t *\n\t * @type {Number}\n\t */\n\tget offset() {\n\t\treturn last( this.path );\n\t}\n\n\t/**\n\t * @param {Number} newOffset\n\t */\n\tset offset( newOffset ) {\n\t\tthis.path[ this.path.length - 1 ] = newOffset;\n\t}\n\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~Position#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\t * @readonly\n\t * @type {module:engine/model/element~Element}\n\t */\n\tget parent() {\n\t\tlet parent = this.root;\n\n\t\tfor ( let i = 0; i < this.path.length - 1; i++ ) {\n\t\t\tparent = parent.getChild( parent.offsetToIndex( this.path[ i ] ) );\n\t\t}\n\n\t\treturn parent;\n\t}\n\n\t/**\n\t * Position {@link module:engine/model/position~Position#offset offset} converted to an index in position's parent node. It is\n\t * equal to the {@link module:engine/model/node~Node#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\t * @readonly\n\t * @type {Number}\n\t */\n\tget index() {\n\t\treturn this.parent.offsetToIndex( this.offset );\n\t}\n\n\t/**\n\t * Returns {@link module:engine/model/text~Text 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\t * @readonly\n\t * @type {module:engine/model/text~Text|null}\n\t */\n\tget textNode() {\n\t\tconst node = this.parent.getChild( this.index );\n\n\t\treturn ( node instanceof Text && node.startOffset < this.offset ) ? node : null;\n\t}\n\n\t/**\n\t * Node directly after this position or `null` if this position is in text node.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/node~Node|null}\n\t */\n\tget nodeAfter() {\n\t\treturn this.textNode === null ? this.parent.getChild( this.index ) : null;\n\t}\n\n\t/**\n\t * Node directly before this position or `null` if this position is in text node.\n\t *\n\t * @readonly\n\t * @type {Node}\n\t */\n\tget nodeBefore() {\n\t\treturn this.textNode === null ? this.parent.getChild( this.index - 1 ) : null;\n\t}\n\n\t/**\n\t * Is `true` if position is at the beginning of its {@link module:engine/model/position~Position#parent parent}, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isAtStart() {\n\t\treturn this.offset === 0;\n\t}\n\n\t/**\n\t * Is `true` if position is at the end of its {@link module:engine/model/position~Position#parent parent}, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isAtEnd() {\n\t\treturn this.offset == this.parent.maxOffset;\n\t}\n\n\t/**\n\t * Checks whether this position is before or after given position.\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {module:engine/model/position~PositionRelation}\n\t */\n\tcompareWith( otherPosition ) {\n\t\tif ( this.root != otherPosition.root ) {\n\t\t\treturn 'different';\n\t\t}\n\n\t\tconst result = compareArrays( this.path, otherPosition.path );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'same':\n\t\t\t\treturn 'same';\n\n\t\t\tcase 'prefix':\n\t\t\t\treturn 'before';\n\n\t\t\tcase 'extension':\n\t\t\t\treturn 'after';\n\n\t\t\tdefault:\n\t\t\t\tif ( this.path[ result ] < otherPosition.path[ result ] ) {\n\t\t\t\t\treturn 'before';\n\t\t\t\t} else {\n\t\t\t\t\treturn 'after';\n\t\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets the farthest position which matches the callback using\n\t * {@link module:engine/model/treewalker~TreeWalker TreeWalker}.\n\t *\n\t * For example:\n\t *\n\t * \t\tgetLastMatchingPosition( value => value.type == 'text' );\n\t * \t\t// <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t *\n\t * \t\tgetLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } );\n\t * \t\t// <paragraph>foo[]</paragraph> -> <paragraph>[]foo</paragraph>\n\t *\n\t * \t\tgetLastMatchingPosition( value => false );\n\t * \t\t// Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/model/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t *\n\t * @returns {module:engine/model/position~Position} The position after the last item which matches the `skip` callback test.\n\t */\n\tgetLastMatchingPosition( skip, options = {} ) {\n\t\toptions.startPosition = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\t\ttreeWalker.skip( skip );\n\n\t\treturn treeWalker.position;\n\t}\n\n\t/**\n\t * Returns a path to this position's parent. Parent path is equal to position {@link module:engine/model/position~Position#path path}\n\t * but without the last item.\n\t *\n\t * This method returns the parent path even if the parent does not exists.\n\t *\n\t * @returns {Array.<Number>} Path to the parent.\n\t */\n\tgetParentPath() {\n\t\treturn this.path.slice( 0, -1 );\n\t}\n\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.<module:engine/model/item~Item>} Array with ancestors.\n\t */\n\tgetAncestors() {\n\t\tif ( this.parent.is( 'documentFragment' ) ) {\n\t\t\treturn [ this.parent ];\n\t\t} else {\n\t\t\treturn this.parent.getAncestors( { includeSelf: true } );\n\t\t}\n\t}\n\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 * @param {module:engine/model/position~Position} position The second position.\n\t * @returns {Array.<Number>} The common path.\n\t */\n\tgetCommonPath( position ) {\n\t\tif ( this.root != position.root ) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// We find on which tree-level start and end have the lowest common ancestor\n\t\tconst cmp = compareArrays( this.path, position.path );\n\t\t// If comparison returned string it means that arrays are same.\n\t\tconst diffAt = ( typeof cmp == 'string' ) ? Math.min( this.path.length, position.path.length ) : cmp;\n\n\t\treturn this.path.slice( 0, diffAt );\n\t}\n\n\t/**\n\t * Returns an {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\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 {module:engine/model/position~Position} position The second position.\n\t * @returns {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor( position ) {\n\t\tconst ancestorsA = this.getAncestors();\n\t\tconst ancestorsB = position.getAncestors();\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\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 * @param {Number} shift Offset shift. Can be a negative value.\n\t * @returns {module:engine/model/position~Position} Shifted position.\n\t */\n\tgetShiftedBy( shift ) {\n\t\tconst shifted = Position.createFromPosition( this );\n\n\t\tconst offset = shifted.offset + shift;\n\t\tshifted.offset = offset < 0 ? 0 : offset;\n\n\t\treturn shifted;\n\t}\n\n\t/**\n\t * Checks whether this position is after given position.\n\t *\n\t * @see module:engine/model/position~Position#isBefore\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if this position is after given position.\n\t */\n\tisAfter( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'after';\n\t}\n\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 *\t\tif ( a.isBefore( b ) && c.isAfter( d ) ) {\n\t *\t\t\t// do A.\n\t *\t\t} else {\n\t *\t\t\t// do B.\n\t *\t\t}\n\t *\n\t * or, if you have only one if-branch:\n\t *\n\t *\t\tif ( !( a.isBefore( b ) && c.isAfter( d ) ) {\n\t *\t\t\t// do B.\n\t *\t\t}\n\t *\n\t * rather than:\n\t *\n\t *\t\tif ( !a.isBefore( b ) || && !c.isAfter( d ) ) {\n\t *\t\t\t// do B.\n\t *\t\t} else {\n\t *\t\t\t// do A.\n\t *\t\t}\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if this position is before given position.\n\t */\n\tisBefore( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'before';\n\t}\n\n\t/**\n\t * Checks whether this position is equal to given position.\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if positions are same.\n\t */\n\tisEqual( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'same';\n\t}\n\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 * **Note:** this method traverses model document so it can be only used when range is up-to-date with model document.\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if positions touch.\n\t */\n\tisTouching( otherPosition ) {\n\t\tlet left = null;\n\t\tlet right = null;\n\t\tconst compare = this.compareWith( otherPosition );\n\n\t\tswitch ( compare ) {\n\t\t\tcase 'same':\n\t\t\t\treturn true;\n\n\t\t\tcase 'before':\n\t\t\t\tleft = Position.createFromPosition( this );\n\t\t\t\tright = Position.createFromPosition( otherPosition );\n\t\t\t\tbreak;\n\n\t\t\tcase 'after':\n\t\t\t\tleft = Position.createFromPosition( otherPosition );\n\t\t\t\tright = Position.createFromPosition( this );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\n\t\t// Cached for optimization purposes.\n\t\tlet leftParent = left.parent;\n\n\t\twhile ( left.path.length + right.path.length ) {\n\t\t\tif ( left.isEqual( right ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif ( left.path.length > right.path.length ) {\n\t\t\t\tif ( left.offset !== leftParent.maxOffset ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tleft.path = left.path.slice( 0, -1 );\n\t\t\t\tleftParent = leftParent.parent;\n\t\t\t\tleft.offset++;\n\t\t\t} else {\n\t\t\t\tif ( right.offset !== 0 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tright.path = right.path.slice( 0, -1 );\n\t\t\t}\n\t\t}\n\t}\n\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 * @protected\n\t * @param {module:engine/model/position~Position} deletePosition Position before the first removed node.\n\t * @param {Number} howMany How many nodes are removed.\n\t * @returns {module:engine/model/position~Position|null} Transformed position or `null`.\n\t */\n\t_getTransformedByDeletion( deletePosition, howMany ) {\n\t\tconst transformed = Position.createFromPosition( this );\n\n\t\t// This position can't be affected if deletion was in a different root.\n\t\tif ( this.root != deletePosition.root ) {\n\t\t\treturn transformed;\n\t\t}\n\n\t\tif ( compareArrays( deletePosition.getParentPath(), this.getParentPath() ) == 'same' ) {\n\t\t\t// If nodes are removed from the node that is pointed by this position...\n\t\t\tif ( deletePosition.offset < this.offset ) {\n\t\t\t\t// And are removed from before an offset of that position...\n\t\t\t\tif ( deletePosition.offset + howMany > this.offset ) {\n\t\t\t\t\t// Position is in removed range, it's no longer in the tree.\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\t// Decrement the offset accordingly.\n\t\t\t\t\ttransformed.offset -= howMany;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( compareArrays( deletePosition.getParentPath(), this.getParentPath() ) == 'prefix' ) {\n\t\t\t// If nodes are removed from a node that is on a path to this position...\n\t\t\tconst i = deletePosition.path.length - 1;\n\n\t\t\tif ( deletePosition.offset <= this.path[ i ] ) {\n\t\t\t\t// And are removed from before next node of that path...\n\t\t\t\tif ( deletePosition.offset + howMany > this.path[ i ] ) {\n\t\t\t\t\t// If the next node of that path is removed return null\n\t\t\t\t\t// because the node containing this position got removed.\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, decrement index on that path.\n\t\t\t\t\ttransformed.path[ i ] -= howMany;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn transformed;\n\t}\n\n\t/**\n\t * Returns a copy of this position that is updated by inserting `howMany` nodes at `insertPosition`.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} insertPosition Position where nodes are inserted.\n\t * @param {Number} howMany How many nodes are inserted.\n\t * @param {Boolean} insertBefore Flag indicating whether nodes are inserted before or after `insertPosition`.\n\t * This is important only when `insertPosition` and this position are same. If that is the case and the flag is\n\t * set to `true`, this position will get transformed. If the flag is set to `false`, it won't.\n\t * @returns {module:engine/model/position~Position} Transformed position.\n\t */\n\t_getTransformedByInsertion( insertPosition, howMany, insertBefore ) {\n\t\tconst transformed = Position.createFromPosition( this );\n\n\t\t// This position can't be affected if insertion was in a different root.\n\t\tif ( this.root != insertPosition.root ) {\n\t\t\treturn transformed;\n\t\t}\n\n\t\tif ( compareArrays( insertPosition.getParentPath(), this.getParentPath() ) == 'same' ) {\n\t\t\t// If nodes are inserted in the node that is pointed by this position...\n\t\t\tif ( insertPosition.offset < this.offset || ( insertPosition.offset == this.offset && insertBefore ) ) {\n\t\t\t\t// And are inserted before an offset of that position...\n\t\t\t\t// \"Push\" this positions offset.\n\t\t\t\ttransformed.offset += howMany;\n\t\t\t}\n\t\t} else if ( compareArrays( insertPosition.getParentPath(), this.getParentPath() ) == 'prefix' ) {\n\t\t\t// If nodes are inserted in a node that is on a path to this position...\n\t\t\tconst i = insertPosition.path.length - 1;\n\n\t\t\tif ( insertPosition.offset <= this.path[ i ] ) {\n\t\t\t\t// And are inserted before next node of that path...\n\t\t\t\t// \"Push\" the index on that path.\n\t\t\t\ttransformed.path[ i ] += howMany;\n\t\t\t}\n\t\t}\n\n\t\treturn transformed;\n\t}\n\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 * @protected\n\t * @param {module:engine/model/position~Position} sourcePosition Position before the first element to move.\n\t * @param {module:engine/model/position~Position} targetPosition Position where moved elements will be inserted.\n\t * @param {Number} howMany How many consecutive nodes to move, starting from `sourcePosition`.\n\t * @param {Boolean} insertBefore Flag indicating whether moved nodes are pasted before or after `insertPosition`.\n\t * This is important only when `targetPosition` and this position are same. If that is the case and the flag is\n\t * set to `true`, this position will get transformed by range insertion. If the flag is set to `false`, it won't.\n\t * @param {Boolean} [sticky] Flag indicating whether this position \"sticks\" to range, that is if it should be moved\n\t * with the moved range if it is equal to one of range's boundaries.\n\t * @returns {module:engine/model/position~Position} Transformed position.\n\t */\n\t_getTransformedByMove( sourcePosition, targetPosition, howMany, insertBefore, sticky ) {\n\t\t// Moving a range removes nodes from their original position. We acknowledge this by proper transformation.\n\t\tlet transformed = this._getTransformedByDeletion( sourcePosition, howMany );\n\n\t\t// Then we update target position, as it could be affected by nodes removal too.\n\t\ttargetPosition = targetPosition._getTransformedByDeletion( sourcePosition, howMany );\n\n\t\tif ( transformed === null || ( sticky && transformed.isEqual( sourcePosition ) ) ) {\n\t\t\t// This position is inside moved range (or sticks to it).\n\t\t\t// In this case, we calculate a combination of this position, move source position and target position.\n\t\t\ttransformed = this._getCombined( sourcePosition, targetPosition );\n\t\t} else {\n\t\t\t// This position is not inside a removed range.\n\t\t\t// In next step, we simply reflect inserting `howMany` nodes, which might further affect the position.\n\t\t\ttransformed = transformed._getTransformedByInsertion( targetPosition, howMany, insertBefore );\n\t\t}\n\n\t\treturn transformed;\n\t}\n\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 *\t\tlet original = new Position( root, [ 2, 3, 1 ] );\n\t *\t\tlet source = new Position( root, [ 2, 2 ] );\n\t *\t\tlet target = new Position( otherRoot, [ 1, 1, 3 ] );\n\t *\t\toriginal._getCombined( source, target ); // path is [ 1, 1, 4, 1 ], root is `otherRoot`\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 * @protected\n\t * @param {module:engine/model/position~Position} source Beginning of the moved range.\n\t * @param {module:engine/model/position~Position} target Position where the range is moved.\n\t * @returns {module:engine/model/position~Position} Combined position.\n\t */\n\t_getCombined( source, target ) {\n\t\tconst i = source.path.length - 1;\n\n\t\t// The first part of a path to combined position is a path to the place where nodes were moved.\n\t\tconst combined = Position.createFromPosition( target );\n\n\t\t// Then we have to update the rest of the path.\n\n\t\t// Fix the offset because this position might be after `from` position and we have to reflect that.\n\t\tcombined.offset = combined.offset + this.path[ i ] - source.offset;\n\n\t\t// Then, add the rest of the path.\n\t\t// If this position is at the same level as `from` position nothing will get added.\n\t\tcombined.path = combined.path.concat( this.path.slice( i + 1 ) );\n\n\t\treturn combined;\n\t}\n\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~Position 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~Item 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 constructors such as:\n\t *\n\t * * {@link module:engine/model/position~Position.createBefore},\n\t * * {@link module:engine/model/position~Position.createAfter},\n\t * * {@link module:engine/model/position~Position.createFromParentAndOffset},\n\t * * {@link module:engine/model/position~Position.createFromPosition}.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tstatic createAt( itemOrPosition, offset ) {\n\t\tif ( itemOrPosition instanceof Position ) {\n\t\t\treturn this.createFromPosition( itemOrPosition );\n\t\t} else {\n\t\t\tconst node = itemOrPosition;\n\n\t\t\tif ( offset == 'end' ) {\n\t\t\t\toffset = node.maxOffset;\n\t\t\t} else if ( offset == 'before' ) {\n\t\t\t\treturn this.createBefore( node );\n\t\t\t} else if ( offset == 'after' ) {\n\t\t\t\treturn this.createAfter( node );\n\t\t\t} else if ( !offset ) {\n\t\t\t\toffset = 0;\n\t\t\t}\n\n\t\t\treturn this.createFromParentAndOffset( node, offset );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a new position, after given {@link module:engine/model/item~Item model item}.\n\t *\n\t * @param {module:engine/model/item~Item} item Item after which the position should be placed.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tstatic createAfter( item ) {\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position after a root element.\n\t\t\t *\n\t\t\t * @error model-position-after-root\n\t\t\t * @param {module:engine/model/item~Item} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-position-after-root: You cannot make a position after root.', { root: item } );\n\t\t}\n\n\t\treturn this.createFromParentAndOffset( item.parent, item.endOffset );\n\t}\n\n\t/**\n\t * Creates a new position, before the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * @param {module:engine/model/item~Item} item Item before which the position should be placed.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tstatic createBefore( item ) {\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position before a root element.\n\t\t\t *\n\t\t\t * @error model-position-before-root\n\t\t\t * @param {module:engine/model/item~Item} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-position-before-root: You cannot make a position before root.', { root: item } );\n\t\t}\n\n\t\treturn this.createFromParentAndOffset( item.parent, item.startOffset );\n\t}\n\n\t/**\n\t * Creates a new position from the parent element and an offset in that element.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} parent Position's parent.\n\t * @param {Number} offset Position's offset.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tstatic createFromParentAndOffset( parent, offset ) {\n\t\tif ( !parent.is( 'element' ) && !parent.is( 'documentFragment' ) ) {\n\t\t\t/**\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: Position parent have to be a element or document fragment.' );\n\t\t}\n\n\t\tconst path = parent.getPath();\n\n\t\tpath.push( offset );\n\n\t\treturn new this( parent.root, path );\n\t}\n\n\t/**\n\t * Creates a new position, which is equal to passed position.\n\t *\n\t * @param {module:engine/model/position~Position} position Position to be cloned.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tstatic createFromPosition( position ) {\n\t\treturn new this( position.root, position.path.slice() );\n\t}\n\n\t/**\n\t * Creates a `Position` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param {Object} json Plain object to be converted to `Position`.\n\t * @returns {module:engine/model/position~Position} `Position` instance created using given plain object.\n\t */\n\tstatic fromJSON( json, doc ) {\n\t\tif ( json.root === '$graveyard' ) {\n\t\t\treturn new Position( doc.graveyard, json.path );\n\t\t}\n\n\t\tif ( !doc.hasRoot( json.root ) ) {\n\t\t\t/**\n\t\t\t * Cannot create position for document. Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error model-position-fromjson-no-root\n\t\t\t * @param {String} rootName\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-position-fromjson-no-root: Cannot create position for document. Root with specified name does not exist.',\n\t\t\t\t{ rootName: json.root }\n\t\t\t);\n\t\t}\n\n\t\treturn new Position( doc.getRoot( json.root ), json.path );\n\t}\n}\n\n/**\n * A flag indicating whether this position is `'before'` or `'after'` or `'same'` as given position.\n * If positions are in different roots `'different'` flag is returned.\n *\n * @typedef {String} module:engine/model/position~PositionRelation\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/position.js\n// module id = null\n// module chunks = ","import listCacheClear from './_listCacheClear';\nimport listCacheDelete from './_listCacheDelete';\nimport listCacheGet from './_listCacheGet';\nimport listCacheHas from './_listCacheHas';\nimport listCacheSet from './_listCacheSet';\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nexport default ListCache;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_ListCache.js\n// module id = null\n// module chunks = ","import hashClear from './_hashClear';\nimport hashDelete from './_hashDelete';\nimport hashGet from './_hashGet';\nimport hashHas from './_hashHas';\nimport hashSet from './_hashSet';\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nexport default Hash;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_Hash.js\n// module id = null\n// module chunks = ","import mapCacheClear from './_mapCacheClear';\nimport mapCacheDelete from './_mapCacheDelete';\nimport mapCacheGet from './_mapCacheGet';\nimport mapCacheHas from './_mapCacheHas';\nimport mapCacheSet from './_mapCacheSet';\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nexport default MapCache;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_MapCache.js\n// module id = null\n// module chunks = ","import ListCache from './_ListCache';\nimport stackClear from './_stackClear';\nimport stackDelete from './_stackDelete';\nimport stackGet from './_stackGet';\nimport stackHas from './_stackHas';\nimport stackSet from './_stackSet';\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n this.__data__ = new ListCache(entries);\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nexport default Stack;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_Stack.js\n// module id = null\n// module chunks = ","/** Built-in value references. */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbol properties of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nfunction getSymbols(object) {\n // Coerce `object` to an object to avoid non-object errors in V8.\n // See https://bugs.chromium.org/p/v8/issues/detail?id=3443 for more details.\n return getOwnPropertySymbols(Object(object));\n}\n\n// Fallback for IE < 11.\nif (!getOwnPropertySymbols) {\n getSymbols = function() {\n return [];\n };\n}\n\nexport default getSymbols;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_getSymbols.js\n// module id = null\n// module chunks = ","import DataView from './_DataView';\nimport Map from './_Map';\nimport Promise from './_Promise';\nimport Set from './_Set';\nimport WeakMap from './_WeakMap';\nimport toSource from './_toSource';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction getTag(value) {\n return objectToString.call(value);\n}\n\n// Fallback for data views, maps, sets, and weak maps in IE 11,\n// for data views in Edge, and promises in Node.js.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = objectToString.call(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : undefined;\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nexport default getTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_getTag.js\n// module id = null\n// module chunks = ","import Stack from './_Stack';\nimport arrayEach from './_arrayEach';\nimport assignValue from './_assignValue';\nimport baseAssign from './_baseAssign';\nimport cloneBuffer from './_cloneBuffer';\nimport copyArray from './_copyArray';\nimport copySymbols from './_copySymbols';\nimport getAllKeys from './_getAllKeys';\nimport getTag from './_getTag';\nimport initCloneArray from './_initCloneArray';\nimport initCloneByTag from './_initCloneByTag';\nimport initCloneObject from './_initCloneObject';\nimport isArray from './isArray';\nimport isBuffer from './isBuffer';\nimport isHostObject from './_isHostObject';\nimport isObject from './isObject';\nimport keys from './keys';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @param {boolean} [isFull] Specify a clone including symbols.\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, isDeep, isFull, customizer, key, object, stack) {\n var result;\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n if (isHostObject(value)) {\n return object ? value : {};\n }\n result = initCloneObject(isFunc ? {} : value);\n if (!isDeep) {\n return copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, baseClone, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (!isArr) {\n var props = isFull ? getAllKeys(value) : keys(value);\n }\n // Recursively populate clone (susceptible to call stack limits).\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));\n });\n return result;\n}\n\nexport default baseClone;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseClone.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/matcher\n */\n\n/**\n * View matcher class.\n * Instance of this class can be used to find {@link module:engine/view/element~Element elements} that match given pattern.\n */\nexport default class Matcher {\n\t/**\n\t * Creates new instance of Matcher.\n\t *\n\t * @param {String|RegExp|Object} [pattern] Match patterns. See {@link module:engine/view/matcher~Matcher#add add method} for\n\t * more information.\n\t */\n\tconstructor( ...pattern ) {\n\t\tthis._patterns = [];\n\n\t\tthis.add( ...pattern );\n\t}\n\n\t/**\n\t * Adds pattern or patterns to matcher instance.\n\t *\n\t * Example patterns matching element's name:\n\t *\n\t *\t\t// String.\n\t *\t\tmatcher.add( 'div' );\n\t *\t\tmatcher.add( { name: 'div' } );\n\t *\n\t *\t\t// Regular expression.\n\t *\t\tmatcher.add( /^\\w/ );\n\t *\t\tmatcher.add( { name: /^\\w/ } );\n\t *\n\t * Example pattern matching element's attributes:\n\t *\n\t *\t\tmatcher.add( {\n\t *\t\t\tattribute: {\n\t *\t\t\t\ttitle: 'foobar',\n\t *\t\t\t\tfoo: /^\\w+/\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * Example patterns matching element's classes:\n\t *\n\t *\t\t// Single class.\n\t *\t\tmatcher.add( {\n\t *\t\t\tclass: 'foobar'\n\t *\t\t} );\n\t *\n\t *\t\t// Single class using regular expression.\n\t *\t\tmatcher.add( {\n\t *\t\t\tclass: /foo.../\n\t *\t\t} );\n\t *\n\t *\t\t// Multiple classes to match.\n\t *\t\tmatcher.add( {\n\t *\t\t\tclass: [ 'baz', 'bar', /foo.../ ]\n\t *\t\t} ):\n\t *\n\t * Example pattern matching element's styles:\n\t *\n\t *\t\tmatcher.add( {\n\t *\t\t\tstyle: {\n\t *\t\t\t\tposition: 'absolute',\n\t *\t\t\t\tcolor: /^\\w*blue$/\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * Example function pattern:\n\t *\n\t *\t\tmatcher.add( ( element ) => {\n\t *\t\t\t// Result of this function will be included in `match`\n\t *\t\t\t// property of the object returned from matcher.match() call.\n\t *\t\t\tif ( element.name === 'div' && element.childCount > 0 ) {\n\t *\t\t\t\treturn { name: true };\n\t *\t\t\t}\n\t *\n\t *\t\t\treturn null;\n\t *\t\t} );\n\t *\n\t * Multiple patterns can be added in one call:\n\t *\n\t * \t\tmatcher.add( 'div', { class: 'foobar' } );\n\t *\n\t * @param {Object|String|RegExp|Function} 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~Element 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 * @param {String|RegExp} [pattern.name] Name or regular expression to match element's name.\n\t * @param {Object} [pattern.attribute] Object with key-value pairs representing attributes to match. Each object key\n\t * represents attribute name. Value under that key can be either a string or a regular expression and it will be\n\t * used to match attribute value.\n\t * @param {String|RegExp|Array} [pattern.class] Class name or array of class names to match. Each name can be\n\t * provided in a form of string or regular expression.\n\t * @param {Object} [pattern.style] Object with key-value pairs representing styles to match. Each object key\n\t * represents style name. Value under that key can be either a string or a regular expression and it will be used\n\t * to match style value.\n\t */\n\tadd( ...pattern ) {\n\t\tfor ( let item of pattern ) {\n\t\t\t// String or RegExp pattern is used as element's name.\n\t\t\tif ( typeof item == 'string' || item instanceof RegExp ) {\n\t\t\t\titem = { name: item };\n\t\t\t}\n\n\t\t\t// Single class name/RegExp can be provided.\n\t\t\tif ( item.class && ( typeof item.class == 'string' || item.class instanceof RegExp ) ) {\n\t\t\t\titem.class = [ item.class ];\n\t\t\t}\n\n\t\t\tthis._patterns.push( item );\n\t\t}\n\t}\n\n\t/**\n\t * Matches elements for currently stored patterns. Returns match information about first found\n\t * {@link module:engine/view/element~Element element}, otherwise returns `null`.\n\t *\n\t * Example of returned object:\n\t *\n\t *\t\t{\n\t *\t\t\telement: <instance of found element>,\n\t *\t\t\tpattern: <pattern used to match found element>,\n\t *\t\t\tmatch: {\n\t *\t\t\t\tname: true,\n\t *\t\t\t\tattribute: [ 'title', 'href' ],\n\t *\t\t\t\tclass: [ 'foo' ],\n\t *\t\t\t\tstyle: [ 'color', 'position' ]\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t * @see module:engine/view/matcher~Matcher#add\n\t * @see module:engine/view/matcher~Matcher#matchAll\n\t * @param {...module:engine/view/element~Element} element View element to match against stored patterns.\n\t * @returns {Object|null} result\n\t * @returns {module:engine/view/element~Element} result.element Matched view element.\n\t * @returns {Object|String|RegExp|Function} result.pattern Pattern that was used to find matched element.\n\t * @returns {Object} result.match Object representing matched element parts.\n\t * @returns {Boolean} [result.match.name] True if name of the element was matched.\n\t * @returns {Array} [result.match.attribute] Array with matched attribute names.\n\t * @returns {Array} [result.match.class] Array with matched class names.\n\t * @returns {Array} [result.match.style] Array with matched style names.\n\t */\n\tmatch( ...element ) {\n\t\tfor ( const singleElement of element ) {\n\t\t\tfor ( const pattern of this._patterns ) {\n\t\t\t\tconst match = isElementMatching( singleElement, pattern );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\telement: singleElement,\n\t\t\t\t\t\tpattern,\n\t\t\t\t\t\tmatch\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\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~Element 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 {...module:engine/view/element~Element} element View element to match against stored patterns.\n\t * @returns {Array.<Object>|null} 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\n\t\tfor ( const singleElement of element ) {\n\t\t\tfor ( const pattern of this._patterns ) {\n\t\t\t\tconst match = isElementMatching( singleElement, pattern );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\tresults.push( {\n\t\t\t\t\t\telement: singleElement,\n\t\t\t\t\t\tpattern,\n\t\t\t\t\t\tmatch\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn results.length > 0 ? results : null;\n\t}\n\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 {String|null} Element name trying to match.\n\t */\n\tgetElementName() {\n\t\tif ( this._patterns.length !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst pattern = this._patterns[ 0 ];\n\t\tconst name = pattern.name;\n\n\t\treturn ( typeof pattern != 'function' && name && !( name instanceof RegExp ) ) ? name : null;\n\t}\n}\n\n// Returns match information if {@link module:engine/view/element~Element element} is matching provided pattern.\n// If element cannot be matched to provided pattern - returns `null`.\n//\n// @param {module:engine/view/element~Element} element\n// @param {Object|String|RegExp|Function} pattern\n// @returns {Object|null} Returns object with match information or null if element is not matching.\nfunction isElementMatching( element, pattern ) {\n\t// If pattern is provided as function - return result of that function;\n\tif ( typeof pattern == 'function' ) {\n\t\treturn pattern( element );\n\t}\n\n\tconst match = {};\n\t// Check element's name.\n\tif ( pattern.name ) {\n\t\tmatch.name = matchName( pattern.name, element.name );\n\n\t\tif ( !match.name ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Check element's attributes.\n\tif ( pattern.attribute ) {\n\t\tmatch.attribute = matchAttributes( pattern.attribute, element );\n\n\t\tif ( !match.attribute ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Check element's classes.\n\tif ( pattern.class ) {\n\t\tmatch.class = matchClasses( pattern.class, element );\n\n\t\tif ( !match.class ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check element's styles.\n\tif ( pattern.style ) {\n\t\tmatch.style = matchStyles( pattern.style, element );\n\n\t\tif ( !match.style ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n// Checks if name can be matched by provided pattern.\n//\n// @param {String|RegExp} pattern\n// @param {String} name\n// @returns {Boolean} Returns `true` if name can be matched, `false` otherwise.\nfunction matchName( pattern, name ) {\n\t// If pattern is provided as RegExp - test against this regexp.\n\tif ( pattern instanceof RegExp ) {\n\t\treturn pattern.test( name );\n\t}\n\n\treturn pattern === name;\n}\n\n// Checks if attributes of provided element can be matched against provided patterns.\n//\n// @param {Object} 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 {module:engine/view/element~Element} element Element which attributes will be tested.\n// @returns {Array|null} Returns array with matched attribute names or `null` if no attributes were matched.\nfunction matchAttributes( patterns, element ) {\n\tconst match = [];\n\n\tfor ( const name in patterns ) {\n\t\tconst pattern = patterns[ name ];\n\n\t\tif ( element.hasAttribute( name ) ) {\n\t\t\tconst attribute = element.getAttribute( name );\n\n\t\t\tif ( pattern instanceof RegExp ) {\n\t\t\t\tif ( pattern.test( attribute ) ) {\n\t\t\t\t\tmatch.push( name );\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t} else if ( attribute === pattern ) {\n\t\t\t\tmatch.push( name );\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n// Checks if classes of provided element can be matched against provided patterns.\n//\n// @param {Array.<String|RegExp>} patterns Array of strings or regular expressions to match against element's classes.\n// @param {module:engine/view/element~Element} element Element which classes will be tested.\n// @returns {Array|null} Returns array with matched class names or `null` if no classes were matched.\nfunction matchClasses( patterns, element ) {\n\tconst match = [];\n\n\tfor ( const pattern of patterns ) {\n\t\tif ( pattern instanceof RegExp ) {\n\t\t\tconst classes = element.getClassNames();\n\n\t\t\tfor ( const name of classes ) {\n\t\t\t\tif ( pattern.test( name ) ) {\n\t\t\t\t\tmatch.push( name );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( match.length === 0 ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} else if ( element.hasClass( pattern ) ) {\n\t\t\tmatch.push( pattern );\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n// Checks if styles of provided element can be matched against provided patterns.\n//\n// @param {Object} 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 {module:engine/view/element~Element} element Element which styles will be tested.\n// @returns {Array|null} Returns array with matched style names or `null` if no styles were matched.\nfunction matchStyles( patterns, element ) {\n\tconst match = [];\n\n\tfor ( const name in patterns ) {\n\t\tconst pattern = patterns[ name ];\n\n\t\tif ( element.hasStyle( name ) ) {\n\t\t\tconst style = element.getStyle( name );\n\n\t\t\tif ( pattern instanceof RegExp ) {\n\t\t\t\tif ( pattern.test( style ) ) {\n\t\t\t\t\tmatch.push( name );\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t} else if ( style === pattern ) {\n\t\t\t\tmatch.push( name );\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/matcher.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/element\n */\n\nimport Node from './node';\nimport Text from './text';\nimport objectToMap from '@ckeditor/ckeditor5-utils/src/objecttomap';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\nimport isPlainObject from '@ckeditor/ckeditor5-utils/src/lib/lodash/isPlainObject';\nimport Matcher from './matcher';\n\n/**\n * View element.\n *\n * Editing engine does not define fixed HTML DTD. This is why the type of the {@link module:engine/view/element~Element} need to\n * be defined by the feature developer. Creating an element you should use {@link module:engine/view/containerelement~ContainerElement}\n * class, {@link module:engine/view/attributeelement~AttributeElement} class or {@link module:engine/view/emptyelement~EmptyElement} class.\n *\n * Note that for view elements which are not created from 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, so\n * these will be instances of the {@link module:engine/view/element~Element}.\n *\n * @extends module:engine/view/node~Node\n */\nexport default class Element extends Node {\n\t/**\n\t * Creates a view element.\n\t *\n\t * Attributes can be passed in various formats:\n\t *\n\t *\t\tnew Element( 'div', { 'class': 'editor', 'contentEditable': 'true' } ); // object\n\t *\t\tnew Element( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t *\t\tnew Element( 'div', mapOfAttributes ); // map\n\t *\n\t * @param {String} name Node name.\n\t * @param {Object|Iterable} [attrs] Collection of attributes.\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]\n\t * List of nodes to be inserted into created element.\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper();\n\n\t\t/**\n\t\t * Name of the element.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Map of attributes, where attributes names are keys and attributes values are values.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map} #_attrs\n\t\t */\n\t\tif ( isPlainObject( attrs ) ) {\n\t\t\tthis._attrs = objectToMap( attrs );\n\t\t} else {\n\t\t\tthis._attrs = new Map( attrs );\n\t\t}\n\n\t\t/**\n\t\t * Array of child nodes.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/view/node~Node>}\n\t\t */\n\t\tthis._children = [];\n\n\t\tif ( children ) {\n\t\t\tthis.insertChildren( 0, children );\n\t\t}\n\n\t\t/**\n\t\t * Set of classes associated with element instance.\n\t\t *\n\t\t * @protected\n\t\t * @member {Set}\n\t\t */\n\t\tthis._classes = new Set();\n\n\t\tif ( this._attrs.has( 'class' ) ) {\n\t\t\t// Remove class attribute and handle it by class set.\n\t\t\tconst classString = this._attrs.get( 'class' );\n\t\t\tparseClasses( this._classes, classString );\n\t\t\tthis._attrs.delete( 'class' );\n\t\t}\n\n\t\t/**\n\t\t * Map of styles.\n\t\t *\n\t\t * @protected\n\t\t * @member {Set} module:engine/view/element~Element#_styles\n\t\t */\n\t\tthis._styles = new Map();\n\n\t\tif ( this._attrs.has( 'style' ) ) {\n\t\t\t// Remove style attribute and handle it by styles map.\n\t\t\tparseInlineStyles( this._styles, this._attrs.get( 'style' ) );\n\t\t\tthis._attrs.delete( 'style' );\n\t\t}\n\n\t\t/**\n\t\t * Map of custom properties.\n\t\t * Custom properties can be added to element instance, will be cloned but not rendered into DOM.\n\t\t *\n\t\t * @protected\n\t\t * @memeber {Map}\n\t\t */\n\t\tthis._customProperties = new Map();\n\t}\n\n\t/**\n\t * Number of element's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this element, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this._children.length === 0;\n\t}\n\n\t/**\n\t * Checks whether given view tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/view/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @param {String} [name] Element name.\n\t * @returns {Boolean}\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'element' || type == this.name;\n\t\t} else {\n\t\t\treturn type == 'element' && name == this.name;\n\t\t}\n\t}\n\n\t/**\n\t * Clones provided element.\n\t *\n\t * @param {Boolean} [deep=false] 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 {module:engine/view/element~Element} Clone of this element.\n\t */\n\tclone( deep = false ) {\n\t\tconst childrenClone = [];\n\n\t\tif ( deep ) {\n\t\t\tfor ( const child of this.getChildren() ) {\n\t\t\t\tchildrenClone.push( child.clone( deep ) );\n\t\t\t}\n\t\t}\n\n\t\t// ContainerElement and AttributeElement should be also cloned properly.\n\t\tconst cloned = new this.constructor( this.name, this._attrs, childrenClone );\n\n\t\t// Classes and styles are cloned separately - this solution is faster than adding them back to attributes and\n\t\t// parse once again in constructor.\n\t\tcloned._classes = new Set( this._classes );\n\t\tcloned._styles = new Map( this._styles );\n\n\t\t// Clone custom properties.\n\t\tcloned._customProperties = new Map( this._customProperties );\n\n\t\t// Clone filler offset method.\n\t\t// We can't define this method in a prototype because it's behavior which\n\t\t// is changed by e.g. toWidget() function from ckeditor5-widget. Perhaps this should be one of custom props.\n\t\tcloned.getFillerOffset = this.getFillerOffset;\n\n\t\treturn cloned;\n\t}\n\n\t/**\n\t * {@link module:engine/view/element~Element#insertChildren 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 * @fires module:engine/view/node~Node#change\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} nodes Node or the list of nodes to be inserted.\n\t * @returns {Number} Number of appended nodes.\n\t */\n\tappendChildren( nodes ) {\n\t\treturn this.insertChildren( this.childCount, nodes );\n\t}\n\n\t/**\n\t * Gets child at the given index.\n\t *\n\t * @param {Number} index Index of child.\n\t * @returns {module:engine/view/node~Node} Child node.\n\t */\n\tgetChild( index ) {\n\t\treturn this._children[ index ];\n\t}\n\n\t/**\n\t * Gets index of the given child node. Returns `-1` if child node is not found.\n\t *\n\t * @param {module:engine/view/node~Node} node Child node.\n\t * @returns {Number} Index of the child node.\n\t */\n\tgetChildIndex( node ) {\n\t\treturn this._children.indexOf( node );\n\t}\n\n\t/**\n\t * Gets child nodes iterator.\n\t *\n\t * @returns {Iterable.<module:engine/view/node~Node>} Child nodes iterator.\n\t */\n\tgetChildren() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\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 {Iterator.<String>} Keys for attributes.\n\t */\n\t* getAttributeKeys() {\n\t\tif ( this._classes.size > 0 ) {\n\t\t\tyield 'class';\n\t\t}\n\n\t\tif ( this._styles.size > 0 ) {\n\t\t\tyield 'style';\n\t\t}\n\n\t\t// This is not an optimal solution because of https://github.com/ckeditor/ckeditor5-engine/issues/454.\n\t\t// It can be simplified to `yield* this._attrs.keys();`.\n\t\tfor ( const key of this._attrs.keys() ) {\n\t\t\tyield key;\n\t\t}\n\t}\n\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 * @returns {Iterable.<*>}\n\t */\n\t* getAttributes() {\n\t\tyield* this._attrs.entries();\n\n\t\tif ( this._classes.size > 0 ) {\n\t\t\tyield [ 'class', this.getAttribute( 'class' ) ];\n\t\t}\n\n\t\tif ( this._styles.size > 0 ) {\n\t\t\tyield [ 'style', this.getAttribute( 'style' ) ];\n\t\t}\n\t}\n\n\t/**\n\t * Gets attribute by key. If attribute is not present - returns undefined.\n\t *\n\t * @param {String} key Attribute key.\n\t * @returns {String|undefined} Attribute value.\n\t */\n\tgetAttribute( key ) {\n\t\tif ( key == 'class' ) {\n\t\t\tif ( this._classes.size > 0 ) {\n\t\t\t\treturn [ ...this._classes ].join( ' ' );\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( key == 'style' ) {\n\t\t\tif ( this._styles.size > 0 ) {\n\t\t\t\tlet styleString = '';\n\n\t\t\t\tfor ( const [ property, value ] of this._styles ) {\n\t\t\t\t\tstyleString += `${ property }:${ value };`;\n\t\t\t\t}\n\n\t\t\t\treturn styleString;\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this._attrs.get( key );\n\t}\n\n\t/**\n\t * Returns a boolean indicating whether an attribute with the specified key exists in the element.\n\t *\n\t * @param {String} key Attribute key.\n\t * @returns {Boolean} `true` if attribute with the specified key exists in the element, false otherwise.\n\t */\n\thasAttribute( key ) {\n\t\tif ( key == 'class' ) {\n\t\t\treturn this._classes.size > 0;\n\t\t}\n\n\t\tif ( key == 'style' ) {\n\t\t\treturn this._styles.size > 0;\n\t\t}\n\n\t\treturn this._attrs.has( key );\n\t}\n\n\t/**\n\t * Adds or overwrite attribute with a specified key and value.\n\t *\n\t * @param {String} key Attribute key.\n\t * @param {String} value Attribute value.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\tsetAttribute( key, value ) {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tif ( key == 'class' ) {\n\t\t\tparseClasses( this._classes, value );\n\t\t} else if ( key == 'style' ) {\n\t\t\tparseInlineStyles( this._styles, value );\n\t\t} else {\n\t\t\tthis._attrs.set( key, value );\n\t\t}\n\t}\n\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 * @param {Number} index Position where nodes should be inserted.\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} nodes Node or the list of nodes to be inserted.\n\t * @fires module:engine/view/node~Node#change\n\t * @returns {Number} Number of inserted nodes.\n\t */\n\tinsertChildren( index, nodes ) {\n\t\tthis._fireChange( 'children', this );\n\t\tlet count = 0;\n\n\t\tnodes = normalize( nodes );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode.remove();\n\t\t\t}\n\n\t\t\tnode.parent = this;\n\n\t\t\tthis._children.splice( index, 0, node );\n\t\t\tindex++;\n\t\t\tcount++;\n\t\t}\n\n\t\treturn count;\n\t}\n\n\t/**\n\t * Removes attribute from the element.\n\t *\n\t * @param {String} key Attribute key.\n\t * @returns {Boolean} Returns true if an attribute existed and has been removed.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\tremoveAttribute( key ) {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\t// Remove class attribute.\n\t\tif ( key == 'class' ) {\n\t\t\tif ( this._classes.size > 0 ) {\n\t\t\t\tthis._classes.clear();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t// Remove style attribute.\n\t\tif ( key == 'style' ) {\n\t\t\tif ( this._styles.size > 0 ) {\n\t\t\t\tthis._styles.clear();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t// Remove other attributes.\n\t\treturn this._attrs.delete( key );\n\t}\n\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 * @param {Number} index Number of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/view/node~Node>} The array of removed nodes.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\tremoveChildren( index, howMany = 1 ) {\n\t\tthis._fireChange( 'children', this );\n\n\t\tfor ( let i = index; i < index + howMany; i++ ) {\n\t\t\tthis._children[ i ].parent = null;\n\t\t}\n\n\t\treturn this._children.splice( index, howMany );\n\t}\n\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\t * @param {module:engine/view/element~Element} otherElement\n\t * @returns {Boolean}\n\t */\n\tisSimilar( otherElement ) {\n\t\tif ( !( otherElement instanceof Element ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If exactly the same Element is provided - return true immediately.\n\t\tif ( this === otherElement ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check element name.\n\t\tif ( this.name != otherElement.name ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check number of attributes, classes and styles.\n\t\tif ( this._attrs.size !== otherElement._attrs.size || this._classes.size !== otherElement._classes.size ||\n\t\t\tthis._styles.size !== otherElement._styles.size ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if attributes are the same.\n\t\tfor ( const [ key, value ] of this._attrs ) {\n\t\t\tif ( !otherElement._attrs.has( key ) || otherElement._attrs.get( key ) !== value ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if classes are the same.\n\t\tfor ( const className of this._classes ) {\n\t\t\tif ( !otherElement._classes.has( className ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if styles are the same.\n\t\tfor ( const [ property, value ] of this._styles ) {\n\t\t\tif ( !otherElement._styles.has( property ) || otherElement._styles.get( property ) !== value ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Adds specified class.\n\t *\n\t *\t\telement.addClass( 'foo' ); // Adds 'foo' class.\n\t *\t\telement.addClass( 'foo', 'bar' ); // Adds 'foo' and 'bar' classes.\n\t *\n\t * @param {...String} className\n\t * @fires module:engine/view/node~Node#change\n\t */\n\taddClass( ...className ) {\n\t\tthis._fireChange( 'attributes', this );\n\t\tclassName.forEach( name => this._classes.add( name ) );\n\t}\n\n\t/**\n\t * Removes specified class.\n\t *\n \t *\t\telement.removeClass( 'foo' ); // Removes 'foo' class.\n\t *\t\telement.removeClass( 'foo', 'bar' ); // Removes both 'foo' and 'bar' classes.\n\t *\n\t * @param {...String} className\n\t * @fires module:engine/view/node~Node#change\n\t */\n\tremoveClass( ...className ) {\n\t\tthis._fireChange( 'attributes', this );\n\t\tclassName.forEach( name => this._classes.delete( name ) );\n\t}\n\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 *\t\telement.hasClass( 'foo' ); // Returns true if 'foo' class is present.\n\t *\t\telement.hasClass( 'foo', 'bar' ); // Returns true if 'foo' and 'bar' classes are both present.\n\t *\n\t * @param {...String} className\n\t */\n\thasClass( ...className ) {\n\t\tfor ( const name of className ) {\n\t\t\tif ( !this._classes.has( name ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns iterator that contains all class names.\n\t *\n\t * @returns {Iterator.<String>}\n\t */\n\tgetClassNames() {\n\t\treturn this._classes.keys();\n\t}\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t *\t\telement.setStyle( 'color', 'red' );\n\t *\t\telement.setStyle( {\n\t *\t\t\tcolor: 'red',\n\t *\t\t\tposition: 'fixed'\n\t *\t\t} );\n\t *\n\t * @param {String|Object} property Property name or object with key - value pairs.\n\t * @param {String} [value] Value to set. This parameter is ignored if object is provided as the first parameter.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\tsetStyle( property, value ) {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tif ( isPlainObject( property ) ) {\n\t\t\tconst keys = Object.keys( property );\n\n\t\t\tfor ( const key of keys ) {\n\t\t\t\tthis._styles.set( key, property[ key ] );\n\t\t\t}\n\t\t} else {\n\t\t\tthis._styles.set( property, value );\n\t\t}\n\t}\n\n\t/**\n\t * Returns style value for given property.\n\t * Undefined is returned if style does not exist.\n\t *\n\t * @param {String} property\n\t * @returns {String|undefined}\n\t */\n\tgetStyle( property ) {\n\t\treturn this._styles.get( property );\n\t}\n\n\t/**\n\t * Returns iterator that contains all style names.\n\t *\n\t * @returns {Iterator.<String>}\n\t */\n\tgetStyleNames() {\n\t\treturn this._styles.keys();\n\t}\n\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 *\t\telement.hasStyle( 'color' ); // Returns true if 'border-top' style is present.\n\t *\t\telement.hasStyle( 'color', 'border-top' ); // Returns true if 'color' and 'border-top' styles are both present.\n\t *\n\t * @param {...String} property\n\t */\n\thasStyle( ...property ) {\n\t\tfor ( const name of property ) {\n\t\t\tif ( !this._styles.has( name ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Removes specified style.\n\t *\n\t *\t\telement.removeStyle( 'color' ); // Removes 'color' style.\n\t *\t\telement.removeStyle( 'color', 'border-top' ); // Removes both 'color' and 'border-top' styles.\n\t *\n\t * @param {...String} property\n\t * @fires module:engine/view/node~Node#change\n\t */\n\tremoveStyle( ...property ) {\n\t\tthis._fireChange( 'attributes', this );\n\t\tproperty.forEach( name => this._styles.delete( name ) );\n\t}\n\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 {Object|String|RegExp|Function} patterns Patterns used to match correct ancestor.\n\t * See {@link module:engine/view/matcher~Matcher}.\n\t * @returns {module:engine/view/element~Element|null} 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\n\t\twhile ( parent ) {\n\t\t\tif ( matcher.match( parent ) ) {\n\t\t\t\treturn parent;\n\t\t\t}\n\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn null;\n\t}\n\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 * @param {String|Symbol} key\n\t * @param {*} value\n\t */\n\tsetCustomProperty( key, value ) {\n\t\tthis._customProperties.set( key, value );\n\t}\n\n\t/**\n\t * Returns the custom property value for the given key.\n\t *\n\t * @param {String|Symbol} key\n\t * @returns {*}\n\t */\n\tgetCustomProperty( key ) {\n\t\treturn this._customProperties.get( key );\n\t}\n\n\t/**\n\t * Removes the custom property stored under the given key.\n\t *\n\t * @param {String|Symbol} key\n\t * @returns {Boolean} Returns true if property was removed.\n\t */\n\tremoveCustomProperty( key ) {\n\t\treturn this._customProperties.delete( key );\n\t}\n\n\t/**\n\t * Returns an iterator which iterates over this element's custom properties.\n\t * Iterator provides [key, value] pair for each stored property.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\t* getCustomProperties() {\n\t\tyield* this._customProperties.entries();\n\t}\n\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 *\t\t'name class=\"class1,class2\" style=\"style1:value1;style2:value2\" attr1=\"val1\" attr2=\"val2\"'\n \t *\n\t * For example:\n\t *\n\t *\t\tconst element = new ViewElement( 'foo' );\n\t *\t\telement.setAttribute( 'banana', '10' );\n\t *\t\telement.setAttribute( 'apple', '20' );\n\t *\t\telement.setStyle( 'color', 'red' );\n\t *\t\telement.setStyle( 'border-color', 'white' );\n\t *\t\telement.addClass( 'baz' );\n\t *\n\t *\t\t// returns 'foo class=\"baz\" style=\"border-color:white;color:red\" apple=\"20\" banana=\"10\"'\n\t *\t\telement.getIdentity();\n\t *\n\t * NOTE: Classes, styles and other attributes are sorted alphabetically.\n\t *\n\t * @returns {String}\n\t */\n\tgetIdentity() {\n\t\tconst classes = Array.from( this._classes ).sort().join( ',' );\n\t\tconst styles = Array.from( this._styles ).map( i => `${ i[ 0 ] }:${ i[ 1 ] }` ).sort().join( ';' );\n\t\tconst attributes = Array.from( this._attrs ).map( i => `${ i[ 0 ] }=\"${ i[ 1 ] }\"` ).sort().join( ' ' );\n\n\t\treturn this.name +\n\t\t\t( classes == '' ? '' : ` class=\"${ classes }\"` ) +\n\t\t\t( styles == '' ? '' : ` style=\"${ styles }\"` ) +\n\t\t\t( attributes == '' ? '' : ` ${ attributes }` );\n\t}\n\n\t/**\n\t * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n\t *\n\t * @abstract\n\t * @method module:engine/view/element~Element#getFillerOffset\n\t */\n}\n\n// Parses inline styles and puts property - value pairs into styles map.\n// Styles map is cleared before insertion.\n//\n// @param {Map.<String, String>} stylesMap Map to insert parsed properties and values.\n// @param {String} stylesString Styles to parse.\nfunction parseInlineStyles( stylesMap, stylesString ) {\n\t// `null` if no quote was found in input string or last found quote was a closing quote. See below.\n\tlet quoteType = null;\n\tlet propertyNameStart = 0;\n\tlet propertyValueStart = 0;\n\tlet propertyName = null;\n\n\tstylesMap.clear();\n\n\t// Do not set anything if input string is empty.\n\tif ( stylesString === '' ) {\n\t\treturn;\n\t}\n\n\t// Fix inline styles that do not end with `;` so they are compatible with algorithm below.\n\tif ( stylesString.charAt( stylesString.length - 1 ) != ';' ) {\n\t\tstylesString = stylesString + ';';\n\t}\n\n\t// Seek the whole string for \"special characters\".\n\tfor ( let i = 0; i < stylesString.length; i++ ) {\n\t\tconst char = stylesString.charAt( i );\n\n\t\tif ( quoteType === null ) {\n\t\t\t// No quote found yet or last found quote was a closing quote.\n\t\t\tswitch ( char ) {\n\t\t\t\tcase ':':\n\t\t\t\t\t// Most of time colon means that property name just ended.\n\t\t\t\t\t// Sometimes however `:` is found inside property value (for example in background image url).\n\t\t\t\t\tif ( !propertyName ) {\n\t\t\t\t\t\t// Treat this as end of property only if property name is not already saved.\n\t\t\t\t\t\t// Save property name.\n\t\t\t\t\t\tpropertyName = stylesString.substr( propertyNameStart, i - propertyNameStart );\n\t\t\t\t\t\t// Save this point as the start of property value.\n\t\t\t\t\t\tpropertyValueStart = i + 1;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase '\"':\n\t\t\t\tcase '\\'':\n\t\t\t\t\t// Opening quote found (this is an opening quote, because `quoteType` is `null`).\n\t\t\t\t\tquoteType = char;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t// eslint-disable-next-line no-case-declarations\n\t\t\t\tcase ';':\n\t\t\t\t\t// Property value just ended.\n\t\t\t\t\t// Use previously stored property value start to obtain property value.\n\t\t\t\t\tconst propertyValue = stylesString.substr( propertyValueStart, i - propertyValueStart );\n\n\t\t\t\t\tif ( propertyName ) {\n\t\t\t\t\t\t// Save parsed part.\n\t\t\t\t\t\tstylesMap.set( propertyName.trim(), propertyValue.trim() );\n\t\t\t\t\t}\n\n\t\t\t\t\tpropertyName = null;\n\n\t\t\t\t\t// Save this point as property name start. Property name starts immediately after previous property value ends.\n\t\t\t\t\tpropertyNameStart = i + 1;\n\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if ( char === quoteType ) {\n\t\t\t// If a quote char is found and it is a closing quote, mark this fact by `null`-ing `quoteType`.\n\t\t\tquoteType = null;\n\t\t}\n\t}\n}\n\n// Parses class attribute and puts all classes into classes set.\n// Classes set s cleared before insertion.\n//\n// @param {Set.<String>} classesSet Set to insert parsed classes.\n// @param {String} classesString String with classes to parse.\nfunction parseClasses( classesSet, classesString ) {\n\tconst classArray = classesString.split( /\\s+/ );\n\tclassesSet.clear();\n\tclassArray.forEach( name => classesSet.add( name ) );\n}\n\n// Converts strings to Text and non-iterables to arrays.\n//\n// @param {String|module:engine/view/node~Node|Iterable.<String|module:engine/view/node~Node>}\n// @return {Iterable.<module:engine/view/node~Node>}\nfunction normalize( nodes ) {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\treturn typeof node == 'string' ? new Text( node ) : node;\n\t\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/element.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/textproxy\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * TextProxy is a wrapper for substring of {@link module:engine/view/text~Text}. Instance of this class is created by\n * {@link module:engine/view/treewalker~TreeWalker} when only a part of {@link module:engine/view/text~Text} needs to be returned.\n *\n * `TextProxy` has an API similar to {@link module:engine/view/text~Text Text} and allows to do most of the common tasks performed\n * on view nodes.\n *\n * **Note:** Some `TextProxy` instances may represent whole text node, not just a part of it.\n * See {@link module:engine/view/textproxy~TextProxy#isPartial}.\n *\n * **Note:** `TextProxy` is a readonly interface.\n *\n * **Note:** `TextProxy` instances are created on the fly basing on the current state of parent {@link module:engine/view/text~Text}.\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 TextProxy is not a {@link module:engine/view/node~Node} so it can not be\n * inserted as a child of {@link module:engine/view/element~Element}.\n *\n * `TextProxy` instances are created by {@link module:engine/view/treewalker~TreeWalker view tree walker}. You should not need to create\n * an instance of this class by your own.\n */\nexport default class TextProxy {\n\t/**\n\t * Creates a text proxy.\n\t *\n\t * @protected\n\t * @param {module:engine/view/text~Text} textNode Text node which part is represented by this text proxy.\n\t * @param {Number} offsetInText Offset in {@link module:engine/view/textproxy~TextProxy#textNode text node}\n\t * from which the text proxy starts.\n\t * @param {Number} length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t * @constructor\n\t */\n\tconstructor( textNode, offsetInText, length ) {\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/text~Text} element which TextProxy is a substring.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/text~Text} module:engine/view/textproxy~TextProxy#textNode\n\t\t */\n\t\tthis.textNode = textNode;\n\n\t\tif ( offsetInText < 0 || offsetInText > textNode.data.length ) {\n\t\t\t/**\n\t\t\t * Given offsetInText value is incorrect.\n\t\t\t *\n\t\t\t * @error view-textproxy-wrong-offsetintext\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-textproxy-wrong-offsetintext: Given offsetInText value is incorrect.' );\n\t\t}\n\n\t\tif ( length < 0 || offsetInText + length > textNode.data.length ) {\n\t\t\t/**\n\t\t\t * Given length value is incorrect.\n\t\t\t *\n\t\t\t * @error view-textproxy-wrong-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-textproxy-wrong-length: Given length value is incorrect.' );\n\t\t}\n\n\t\t/**\n\t\t * Text data represented by this text proxy.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} module:engine/view/textproxy~TextProxy#data\n\t\t */\n\t\tthis.data = textNode.data.substring( offsetInText, offsetInText + length );\n\n\t\t/**\n\t\t * Offset in the `textNode` where this `TextProxy` instance starts.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} module:engine/view/textproxy~TextProxy#offsetInText\n\t\t */\n\t\tthis.offsetInText = offsetInText;\n\t}\n\n\t/**\n\t * Flag indicating whether `TextProxy` instance covers only part of the original {@link module:engine/view/text~Text 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~TextProxy#textNode textNode}\n\t * ({@link module:engine/view/textproxy~TextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t * text node size.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isPartial() {\n\t\treturn this.data.length !== this.textNode.data.length;\n\t}\n\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\t * @readonly\n\t * @type {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|null}\n\t */\n\tget parent() {\n\t\treturn this.textNode.parent;\n\t}\n\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\t * @readonly\n\t * @type {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.textNode.root;\n\t}\n\n\t/**\n\t * {@link module:engine/view/document~Document View document} that owns this text proxy, or `null` if the text proxy is inside\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/document~Document|null}\n\t */\n\tget document() {\n\t\treturn this.textNode.document;\n\t}\n\n\t/**\n\t * Checks whether given view tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/view/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'textProxy';\n\t}\n\n\t/**\n\t * Returns ancestors array of this text proxy.\n\t *\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` {#textNode} will be also included in parent's array.\n\t * @param {Boolean} [options.parentFirst=false] 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} Array with ancestors.\n\t */\n\tgetAncestors( options = { includeSelf: false, parentFirst: false } ) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this.textNode : this.parent;\n\n\t\twhile ( parent !== null ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/textproxy.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/containerelement\n */\n\nimport Element from './element';\n\n/**\n * Containers are elements which define document structure. They define boundaries for\n * {@link module:engine/view/attributeelement~AttributeElement attributes}. They are mostly use for block elements like `<p>` or `<div>`.\n *\n * Editing engine does not define fixed HTML DTD. This is why the type of the {@link module:engine/view/element~Element} need to\n * be defined by the feature developer.\n *\n * Creating an element you should use `ContainerElement` class or {@link module:engine/view/attributeelement~AttributeElement}. This is\n * important to define the type of the element because of two reasons:\n *\n * Firstly, {@link module:engine/view/domconverter~DomConverter} needs the information what is an editable block to convert elements to\n * DOM properly. {@link module:engine/view/domconverter~DomConverter} will ensure that `ContainerElement` is editable and it is possible\n * to put caret inside it, even if the container is empty.\n *\n * Secondly, {@link module:engine/view/writer~writer view writer} uses this information.\n * Nodes {@link module:engine/view/writer~writer.breakAttributes breaking} and {@link module:engine/view/writer~writer.mergeAttributes\n * merging}\n * is performed only in a bounds of a container nodes.\n *\n * For instance if `<p>` is an container and `<b>` is attribute:\n *\n *\t\t<p><b>fo^o</b></p>\n *\n * {@link module:engine/view/writer~writer.breakAttributes breakAttributes} will create:\n *\n *\t\t<p><b>fo</b><b>o</b></p>\n *\n * There might be a need to mark `<span>` element as a container node, for example in situation when it will be a\n * container of an inline widget:\n *\n *\t\t<span color=\"red\">foobar</span>\t\t// attribute\n *\t\t<span data-widget>foobar</span>\t\t// container\n *\n * @extends module:engine/view/element~Element\n */\nexport default class ContainerElement extends Element {\n\t/**\n\t * Creates a container element.\n\t *\n\t * @see module:engine/view/element~Element\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper( name, attrs, children );\n\n\t\t/**\n\t\t * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {Number|null} Block filler offset or `null` if block filler is not needed.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'containerElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'containerElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n}\n\n// Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n//\n// @returns {Number|null} Block filler offset or `null` if block filler is not needed.\nfunction getFillerOffset() {\n\tfor ( const child of this.getChildren() ) {\n\t\t// If there's any non-UI element don't render the bogus.\n\t\tif ( !child.is( 'uiElement' ) ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// If there are only UI elements render the bogus at the end of the element.\n\treturn this.childCount;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/containerelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/editableelement\n */\n\nimport ContainerElement from './containerelement';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\n\nconst documentSymbol = Symbol( 'document' );\n\n/**\n * Editable element which can be a {@link module:engine/view/rooteditableelement~RootEditableElement root}\n * or nested editable area in the editor.\n *\n * Editable is automatically read-only when its {module:engine/view/document~Document Document} is read-only.\n *\n * @extends module:engine/view/containerelement~ContainerElement\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class EditableElement extends ContainerElement {\n\t/**\n\t * Creates an editable element.\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper( name, attrs, children );\n\n\t\t/**\n\t\t * Whether the editable is in read-write or read-only mode.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} module:engine/view/editableelement~EditableElement#isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * Whether the editable is focused.\n\t\t *\n\t\t * This property updates when {@link module:engine/view/document~Document#isFocused document.isFocused} is changed and after each\n\t\t * {@link module:engine/view/document~Document#render render} method call.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} module:engine/view/editableelement~EditableElement#isFocused\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * The {@link module:engine/view/document~Document} which is an owner of this root.\n\t\t * Can only by set once.\n\t\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-editableelement-document-already-set`\n\t\t * when document is already set.\n\t\t *\n\t\t * @member {module:engine/view/document~Document} #document\n\t\t */\n\t}\n\n\tget document() {\n\t\treturn this.getCustomProperty( documentSymbol );\n\t}\n\n\tset document( document ) {\n\t\tif ( this.getCustomProperty( documentSymbol ) ) {\n\t\t\t/**\n\t\t\t * View document is already set. It can only be set once.\n\t\t\t *\n\t\t\t * @error view-editableelement-document-already-set\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-editableelement-document-already-set: View document is already set.' );\n\t\t}\n\n\t\tthis.setCustomProperty( documentSymbol, document );\n\n\t\tthis.bind( 'isReadOnly' ).to( document );\n\n\t\tthis.bind( 'isFocused' ).to(\n\t\t\tdocument,\n\t\t\t'isFocused',\n\t\t\tisFocused => isFocused && document.selection.editableElement == this\n\t\t);\n\n\t\t// Update focus state before each rendering. Rendering should not change neither the selection nor the value of\n\t\t// document.isFocused property.\n\t\tthis.listenTo( document, 'render', () => {\n\t\t\tthis.isFocused = document.isFocused && document.selection.editableElement == this;\n\t\t}, { priority: 'high' } );\n\t}\n}\n\nmix( EditableElement, ObservableMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/editableelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/range\n */\n\nimport Position from './position';\nimport TreeWalker from './treewalker';\n\n/**\n * Tree view range.\n */\nexport default class Range {\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~Position} instances basing on passed values.\n\t *\n\t * @param {module:engine/view/position~Position} start Start position.\n\t * @param {module:engine/view/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t */\n\tconstructor( start, end = null ) {\n\t\t/**\n\t\t * Start position.\n\t\t *\n\t\t * @member {module:engine/view/position~Position}\n\t\t */\n\t\tthis.start = Position.createFromPosition( start );\n\n\t\t/**\n\t\t * End position.\n\t\t *\n\t\t * @member {module:engine/view/position~Position}\n\t\t */\n\t\tthis.end = end ? Position.createFromPosition( end ) : Position.createFromPosition( start );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n\t * them together with additional information like length or {@link module:engine/view/position~Position positions},\n\t * grouped as {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * This iterator uses {@link module:engine/view/treewalker~TreeWalker TreeWalker} with `boundaries` set to this range and\n\t * `ignoreElementEnd` option\n\t * set to `true`.\n\t *\n\t * @returns {Iterable.<module:engine/view/treewalker~TreeWalkerValue>}\n\t */\n\t* [ Symbol.iterator ]() {\n\t\tyield* new TreeWalker( { boundaries: this, ignoreElementEnd: true } );\n\t}\n\n\t/**\n\t * Returns whether the range is collapsed, that is it start and end positions are equal.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this.start.isEqual( this.end );\n\t}\n\n\t/**\n\t * Returns whether this range is flat, that is if {@link module:engine/view/range~Range#start start} position and\n\t * {@link module:engine/view/range~Range#end end} position are in the same {@link module:engine/view/position~Position#parent parent}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isFlat() {\n\t\treturn this.start.parent === this.end.parent;\n\t}\n\n\t/**\n\t * Range root element.\n\t *\n\t * @type {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.start.root;\n\t}\n\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 * \t\t<p>Foo</p><p><b>{Bar}</b></p> -> <p>Foo</p>[<p><b>Bar</b>]</p>\n\t * \t\t<p><b>foo</b>{bar}<span></span></p> -> <p><b>foo[</b>bar<span></span>]</p>\n\t *\n\t * Note that in the sample above:\n\t * - `<p>` have type of {@link module:engine/view/containerelement~ContainerElement},\n\t * - `<b>` have type of {@link module:engine/view/attributeelement~AttributeElement},\n\t * - `<span>` have type of {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * @returns {module:engine/view/range~Range} 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\n\t\t// Fix positions, in case if they are in Text node.\n\t\tif ( start.parent.is( 'text' ) && start.isAtStart ) {\n\t\t\tstart = Position.createBefore( start.parent );\n\t\t}\n\n\t\tif ( end.parent.is( 'text' ) && end.isAtEnd ) {\n\t\t\tend = Position.createAfter( end.parent );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\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 * \t\t<p>Foo</p>[<p><b>Bar</b>]</p> -> <p>Foo</p><p><b>{Bar}</b></p>\n\t * \t\t<p><b>foo[</b>bar<span></span>]</p> -> <p><b>foo</b>{bar}<span></span></p>\n\t *\n\t * Note that in the sample above:\n\t * - `<p>` have type of {@link module:engine/view/containerelement~ContainerElement},\n\t * - `<b>` have type of {@link module:engine/view/attributeelement~AttributeElement},\n\t * - `<span>` have type of {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * @returns {module:engine/view/range~Range} Shrink range.\n\t */\n\tgetTrimmed() {\n\t\tlet start = this.start.getLastMatchingPosition( enlargeTrimSkip );\n\n\t\tif ( start.isAfter( this.end ) || start.isEqual( this.end ) ) {\n\t\t\treturn new Range( start, start );\n\t\t}\n\n\t\tlet end = this.end.getLastMatchingPosition( enlargeTrimSkip, { direction: 'backward' } );\n\t\tconst nodeAfterStart = start.nodeAfter;\n\t\tconst nodeBeforeEnd = end.nodeBefore;\n\n\t\t// Because TreeWalker prefers positions next to text node, we need to move them manually into these text nodes.\n\t\tif ( nodeAfterStart && nodeAfterStart.is( 'text' ) ) {\n\t\t\tstart = new Position( nodeAfterStart, 0 );\n\t\t}\n\n\t\tif ( nodeBeforeEnd && nodeBeforeEnd.is( 'text' ) ) {\n\t\t\tend = new Position( nodeBeforeEnd, nodeBeforeEnd.data.length );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Two ranges are equal if their start and end positions are equal.\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to compare with.\n\t * @returns {Boolean} `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\n\t/**\n\t * Checks whether this range contains given {@link module:engine/view/position~Position position}.\n\t *\n\t * @param {module:engine/view/position~Position} position Position to check.\n\t * @returns {Boolean} `true` if given {@link module:engine/view/position~Position position} is contained in this range,\n\t * `false` otherwise.\n\t */\n\tcontainsPosition( position ) {\n\t\treturn position.isAfter( this.start ) && position.isBefore( this.end );\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link module:engine/view/range~Range range}.\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to check.\n\t * @param {Boolean} [loose=false] 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/view/range~Range range} boundaries are contained by this range, `false`\n\t * otherwise.\n\t */\n\tcontainsRange( otherRange, loose = false ) {\n\t\tif ( otherRange.isCollapsed ) {\n\t\t\tloose = false;\n\t\t}\n\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\n\t\treturn containsStart && containsEnd;\n\t}\n\n\t/**\n\t * Computes which part(s) of this {@link module:engine/view/range~Range range} is not a part of given\n\t * {@link module:engine/view/range~Range range}.\n\t * Returned array contains zero, one or two {@link module:engine/view/range~Range ranges}.\n\t *\n\t * Examples:\n\t *\n\t *\t\tlet foo = new Text( 'foo' );\n\t *\t\tlet img = new ContainerElement( 'img' );\n\t *\t\tlet bar = new Text( 'bar' );\n\t *\t\tlet p = new ContainerElement( 'p', null, [ foo, img, bar ] );\n\t *\n\t *\t\tlet range = new Range( new Position( foo, 2 ), new Position( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t *\t\tlet otherRange = new Range( new Position( foo, 1 ), new Position( bar, 2 ); \"oo\", img, \"ba\" are in range.\n\t *\t\tlet transformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has no ranges because `otherRange` contains `range`\n\t *\n\t *\t\totherRange = new Range( new Position( foo, 1 ), new Position( p, 2 ); // \"oo\", img are in range.\n\t *\t\ttransformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has one range: from ( p, 2 ) to ( bar, 1 )\n\t *\n\t *\t\totherRange = new Range( new Position( p, 1 ), new Position( p, 2 ) ); // img is in range.\n\t *\t\ttransformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has two ranges: from ( foo, 1 ) to ( p, 1 ) and from ( p, 2 ) to ( bar, 1 )\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to differentiate against.\n\t * @returns {Array.<module:engine/view/range~Range>} The difference between ranges.\n\t */\n\tgetDifference( otherRange ) {\n\t\tconst ranges = [];\n\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect.\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the start to the middle of this range.\n\t\t\t\tranges.push( new Range( this.start, otherRange.start ) );\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the middle of this range to the end.\n\t\t\t\tranges.push( new Range( otherRange.end, this.end ) );\n\t\t\t}\n\t\t} else {\n\t\t\t// Ranges do not intersect, return the original range.\n\t\t\tranges.push( Range.createFromRange( this ) );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an intersection of this {@link module:engine/view/range~Range range} and given {@link module:engine/view/range~Range 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 *\t\tlet foo = new Text( 'foo' );\n\t *\t\tlet img = new ContainerElement( 'img' );\n\t *\t\tlet bar = new Text( 'bar' );\n\t *\t\tlet p = new ContainerElement( 'p', null, [ foo, img, bar ] );\n\t *\n\t *\t\tlet range = new Range( new Position( foo, 2 ), new Position( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t *\t\tlet otherRange = new Range( new Position( foo, 1 ), new Position( p, 2 ); // \"oo\", img are in range.\n\t *\t\tlet transformed = range.getIntersection( otherRange ); // range from ( foo, 1 ) to ( p, 2 ).\n\t *\n\t *\t\totherRange = new Range( new Position( bar, 1 ), new Position( bar, 3 ); \"ar\" is in range.\n\t *\t\ttransformed = range.getIntersection( otherRange ); // null - no common part.\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to check for intersection.\n\t * @returns {module:engine/view/range~Range|null} 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\t// Ranges intersect, so a common range will be returned.\n\t\t\t// At most, it will be same as this range.\n\t\t\tlet commonRangeStart = this.start;\n\t\t\tlet commonRangeEnd = this.end;\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means thaNt we have to\n\t\t\t\t// shrink common range to the given range start.\n\t\t\t\tcommonRangeStart = otherRange.start;\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// shrink common range to the given range end.\n\t\t\t\tcommonRangeEnd = otherRange.end;\n\t\t\t}\n\n\t\t\treturn new Range( commonRangeStart, commonRangeEnd );\n\t\t}\n\n\t\t// Ranges do not intersect, so they do not have common part.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/view/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t * @param {module:engine/view/position~Position} [options.startPosition]\n\t * @param {Boolean} [options.singleCharacters=false]\n\t * @param {Boolean} [options.shallow=false]\n\t * @param {Boolean} [options.ignoreElementEnd=false]\n\t */\n\tgetWalker( options = {} ) {\n\t\toptions.boundaries = this;\n\n\t\treturn new TreeWalker( options );\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of range's both ends (in which the entire range is contained).\n\t *\n\t * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor() {\n\t\treturn this.start.getCommonAncestor( this.end );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n\t * them.\n\t *\n\t * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n\t * set to `true`. However it returns only {@link module:engine/view/item~Item items},\n\t * not {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t * @returns {Iterable.<module:engine/view/item~Item>}\n\t */\n\t* getItems( options = {} ) {\n\t\toptions.boundaries = this;\n\t\toptions.ignoreElementEnd = true;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.item;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/view/position~Position positions} that are boundaries or\n\t * contained in this range.\n\t *\n\t * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n\t * {@link module:engine/view/position~Position positions}, not {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t * @returns {Iterable.<module:engine/view/position~Position>}\n\t */\n\t* getPositions( options = {} ) {\n\t\toptions.boundaries = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tyield treeWalker.position;\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.nextPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Checks and returns whether this range intersects with given range.\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to compare with.\n\t * @returns {Boolean} 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\n\t/**\n\t * Creates a range from given parents and offsets.\n\t *\n\t * @param {module:engine/view/element~Element} startElement Start position parent element.\n\t * @param {Number} startOffset Start position offset.\n\t * @param {module:engine/view/element~Element} endElement End position parent element.\n\t * @param {Number} endOffset End position offset.\n\t * @returns {module:engine/view/range~Range} Created range.\n\t */\n\tstatic createFromParentsAndOffsets( startElement, startOffset, endElement, endOffset ) {\n\t\treturn new this(\n\t\t\tnew Position( startElement, startOffset ),\n\t\t\tnew Position( endElement, endOffset )\n\t\t);\n\t}\n\n\t/**\n\t * Creates and returns a new instance of Range which is equal to passed range.\n\t *\n\t * @param {module:engine/view/range~Range} range Range to clone.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tstatic createFromRange( range ) {\n\t\treturn new this( range.start, range.end );\n\t}\n\n\t/**\n\t * Creates a new range, spreading from specified {@link module:engine/view/position~Position 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 * @param {module:engine/view/position~Position} position Beginning of the range.\n\t * @param {Number} shift How long the range should be.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tstatic createFromPositionAndShift( position, shift ) {\n\t\tconst start = position;\n\t\tconst end = position.getShiftedBy( shift );\n\n\t\treturn shift > 0 ? new this( start, end ) : new this( end, start );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element 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 {module:engine/view/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tstatic createIn( element ) {\n\t\treturn this.createFromParentsAndOffsets( element, 0, element, element.childCount );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @param {module:engine/view/item~Item} item\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tstatic createOn( item ) {\n\t\treturn this.createFromPositionAndShift( Position.createBefore( item ), 1 );\n\t}\n\n\t/**\n\t * Creates a collapsed range at given {@link module:engine/view/position~Position position}\n\t * or on the given {@link module:engine/view/item~Item item}.\n\t *\n\t * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tstatic createCollapsedAt( itemOrPosition, offset ) {\n\t\tconst start = Position.createAt( itemOrPosition, offset );\n\t\tconst end = Position.createFromPosition( start );\n\n\t\treturn new Range( start, end );\n\t}\n}\n\n// Function used by getEnlarged and getTrimmed methods.\nfunction enlargeTrimSkip( value ) {\n\tif ( value.item.is( 'attributeElement' ) || value.item.is( 'uiElement' ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/range.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/mapper\n */\n\nimport ModelPosition from '../model/position';\nimport ModelRange from '../model/range';\n\nimport ViewPosition from '../view/position';\nimport ViewRange from '../view/range';\nimport ViewText from '../view/text';\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Maps elements and positions between {@link module:engine/view/document~Document view} and {@link module:engine/model/model model}.\n *\n * Mapper use 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 complex model to/from view relations, you may provide custom callbacks for\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 {@link module:engine/conversion/mapper~Mapper#toViewPosition toViewPosition}\n * and {@link module:engine/conversion/mapper~Mapper#toModelPosition toModelPosition} methods. `Mapper` adds it's own default callbacks\n * with `'lowest'` priority. To override default `Mapper` mapping, add custom callback with higher priority and\n * stop the event.\n */\nexport default class Mapper {\n\t/**\n\t * Creates an instance of the mapper.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Model element to view element mapping.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap}\n\t\t */\n\t\tthis._modelToViewMapping = new WeakMap();\n\n\t\t/**\n\t\t * View element to model element mapping.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap}\n\t\t */\n\t\tthis._viewToModelMapping = new WeakMap();\n\n\t\t/**\n\t\t * A map containing callbacks between view element names and functions evaluating length of view elements\n\t\t * in model.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._viewToModelLengthCallbacks = new Map();\n\n\t\t// Default mapper algorithm for mapping model position to view position.\n\t\tthis.on( 'modelToViewPosition', ( evt, data ) => {\n\t\t\tif ( data.viewPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst viewContainer = this._modelToViewMapping.get( data.modelPosition.parent );\n\n\t\t\tdata.viewPosition = this._findPositionIn( viewContainer, data.modelPosition.offset );\n\t\t}, { priority: 'low' } );\n\n\t\t// Default mapper algorithm for mapping view position to model position.\n\t\tthis.on( 'viewToModelPosition', ( evt, data ) => {\n\t\t\tif ( data.modelPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet viewBlock = data.viewPosition.parent;\n\t\t\tlet modelParent = this._viewToModelMapping.get( viewBlock );\n\n\t\t\twhile ( !modelParent ) {\n\t\t\t\tviewBlock = viewBlock.parent;\n\t\t\t\tmodelParent = this._viewToModelMapping.get( viewBlock );\n\t\t\t}\n\n\t\t\tconst modelOffset = this._toModelOffset( data.viewPosition.parent, data.viewPosition.offset, viewBlock );\n\n\t\t\tdata.modelPosition = ModelPosition.createFromParentAndOffset( modelParent, modelOffset );\n\t\t}, { priority: 'low' } );\n\t}\n\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 {module:engine/model/element~Element} modelElement Model element.\n\t * @param {module:engine/view/element~Element} 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\n\t/**\n\t * Unbinds given {@link module:engine/view/element~Element view element} from the map.\n\t *\n\t * @param {module:engine/view/element~Element} viewElement View element to unbind.\n\t */\n\tunbindViewElement( viewElement ) {\n\t\tconst modelElement = this.toModelElement( viewElement );\n\n\t\tthis._unbindElements( modelElement, viewElement );\n\t}\n\n\t/**\n\t * Unbinds given {@link module:engine/model/element~Element model element} from the map.\n\t *\n\t * @param {module:engine/model/element~Element} modelElement Model element to unbind.\n\t */\n\tunbindModelElement( modelElement ) {\n\t\tconst viewElement = this.toViewElement( modelElement );\n\n\t\tthis._unbindElements( modelElement, viewElement );\n\t}\n\n\t/**\n\t * Removes all model to view and view to model bindings.\n\t */\n\tclearBindings() {\n\t\tthis._modelToViewMapping = new WeakMap();\n\t\tthis._viewToModelMapping = new WeakMap();\n\t}\n\n\t/**\n\t * Gets the corresponding model element.\n\t *\n\t * **Note:** {@link module:engine/view/uielement~UIElement} does not have corresponding element in model.\n\t *\n\t * @param {module:engine/view/element~Element} viewElement View element.\n\t * @returns {module:engine/model/element~Element|undefined} Corresponding model element or `undefined` if not found.\n\t */\n\ttoModelElement( viewElement ) {\n\t\treturn this._viewToModelMapping.get( viewElement );\n\t}\n\n\t/**\n\t * Gets the corresponding view element.\n\t *\n\t * @param {module:engine/model/element~Element} modelElement Model element.\n\t * @returns {module:engine/view/element~Element|undefined} Corresponding view element or `undefined` if not found.\n\t */\n\ttoViewElement( modelElement ) {\n\t\treturn this._modelToViewMapping.get( modelElement );\n\t}\n\n\t/**\n\t * Gets the corresponding model range.\n\t *\n\t * @param {module:engine/view/range~Range} viewRange View range.\n\t * @returns {module:engine/model/range~Range} Corresponding model range.\n\t */\n\ttoModelRange( viewRange ) {\n\t\treturn new ModelRange( this.toModelPosition( viewRange.start ), this.toModelPosition( viewRange.end ) );\n\t}\n\n\t/**\n\t * Gets the corresponding view range.\n\t *\n\t * @param {module:engine/model/range~Range} modelRange Model range.\n\t * @returns {module:engine/view/range~Range} Corresponding view range.\n\t */\n\ttoViewRange( modelRange ) {\n\t\treturn new ViewRange( this.toViewPosition( modelRange.start ), this.toViewPosition( modelRange.end ) );\n\t}\n\n\t/**\n\t * Gets the corresponding model position.\n\t *\n\t * @fires viewToModelPosition\n\t * @param {module:engine/view/position~Position} viewPosition View position.\n\t * @returns {module:engine/model/position~Position} 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\n\t\tthis.fire( 'viewToModelPosition', data );\n\n\t\treturn data.modelPosition;\n\t}\n\n\t/**\n\t * Gets the corresponding view position.\n\t *\n\t * @fires modelToViewPosition\n\t * @param {module:engine/model/position~Position} modelPosition Model position.\n\t * @returns {module:engine/view/position~Position} Corresponding view position.\n\t */\n\ttoViewPosition( modelPosition ) {\n\t\tconst data = {\n\t\t\tmodelPosition,\n\t\t\tmapper: this\n\t\t};\n\n\t\tthis.fire( 'modelToViewPosition', data );\n\n\t\treturn data.viewPosition;\n\t}\n\n\t/**\n\t * Registers a callback that evaluates the length in the model of a view element with 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 view element in model.\n\t *\n\t *\t\t// List item in view may contain nested list, which have other list items. In model though,\n\t *\t\t// the lists are represented by flat structure. Because of those differences, length of list view element\n\t *\t\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 *\t\tfunction getViewListItemLength( element ) {\n\t *\t\t\tlet length = 1;\n\t *\n\t *\t\t\tfor ( let child of element.getChildren() ) {\n\t *\t\t\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t *\t\t\t\t\tfor ( let item of child.getChildren() ) {\n\t *\t\t\t\t\t\tlength += getViewListItemLength( item );\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\n\t *\t\t\treturn length;\n\t *\t\t}\n\t *\n\t *\t\tmapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t *\n\t * @param {String} viewElementName Name of view element for which callback is registered.\n\t * @param {Function} lengthCallback Function return a length of view element instance in model.\n\t */\n\tregisterViewToModelLength( viewElementName, lengthCallback ) {\n\t\tthis._viewToModelLengthCallbacks.set( viewElementName, lengthCallback );\n\t}\n\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 *\t\t<p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, p ) -> 5\n\t *\n\t * Is a sum of:\n\t *\n\t *\t\t<p>foo|<b>bar</b></p> // _toModelOffset( p, 3, p ) -> 3\n\t *\t\t<p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, b ) -> 2\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} viewParent Position parent.\n\t * @param {Number} viewOffset Position offset.\n\t * @param {module:engine/view/element~Element} viewBlock Block used as a base to calculate offset.\n\t * @returns {Number} Offset in the model.\n\t */\n\t_toModelOffset( viewParent, viewOffset, viewBlock ) {\n\t\tif ( viewBlock != viewParent ) {\n\t\t\t// See example.\n\t\t\tconst offsetToParentStart = this._toModelOffset( viewParent.parent, viewParent.index, viewBlock );\n\t\t\tconst offsetInParent = this._toModelOffset( viewParent, viewOffset, viewParent );\n\n\t\t\treturn offsetToParentStart + offsetInParent;\n\t\t}\n\n\t\t// viewBlock == viewParent, so we need to calculate the offset in the parent element.\n\n\t\t// If the position is a text it is simple (\"ba|r\" -> 2).\n\t\tif ( viewParent.is( 'text' ) ) {\n\t\t\treturn viewOffset;\n\t\t}\n\n\t\t// If the position is in an element we need to sum lengths of siblings ( <b> bar </b> foo | -> 3 + 3 = 6 ).\n\t\tlet modelOffset = 0;\n\n\t\tfor ( let i = 0; i < viewOffset; i++ ) {\n\t\t\tmodelOffset += this.getModelLength( viewParent.getChild( i ) );\n\t\t}\n\n\t\treturn modelOffset;\n\t}\n\n\t/**\n\t * Removes binding between given elements.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} modelElement Model element to unbind.\n\t * @param {module:engine/view/element~Element} viewElement View element to unbind.\n\t */\n\t_unbindElements( modelElement, viewElement ) {\n\t\tthis._viewToModelMapping.delete( viewElement );\n\t\tthis._modelToViewMapping.delete( modelElement );\n\t}\n\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 {@link #registerViewToModelLength length mapping callback} is provided for given `viewNode` it is used to\n\t * evaluate model length (`viewNode` is used as first and only parameter passed to the callback),\n\t * * length of a {@link module:engine/view/text~Text text node} is equal to the length of it's\n\t * {@link module:engine/view/text~Text#data data},\n\t * * length of a {@link module:engine/view/uielement~UIElement ui element} is equal to 0,\n\t * * length of a mapped {@link module:engine/view/element~Element element} is equal to 1,\n\t * * length of a not-mapped {@link module:engine/view/element~Element element} is equal to the length of it's children.\n\t *\n\t * Examples:\n\t *\n\t *\t\tfoo -> 3 // Text length is equal to it's data length.\n\t *\t\t<p>foo</p> -> 1 // Length of an element which is mapped is by default equal to 1.\n\t *\t\t<b>foo</b> -> 3 // Length of an element which is not mapped is a length of its children.\n\t *\t\t<div><p>x</p><p>y</p></div> -> 2 // Assuming that <div> is not mapped and <p> are mapped.\n\t *\n\t * @param {module:engine/view/element~Element} viewNode View node.\n\t * @returns {Number} Length of the node in the tree model.\n\t */\n\tgetModelLength( viewNode ) {\n\t\tif ( this._viewToModelLengthCallbacks.get( viewNode.name ) ) {\n\t\t\tconst callback = this._viewToModelLengthCallbacks.get( viewNode.name );\n\n\t\t\treturn callback( viewNode );\n\t\t} else if ( this._viewToModelMapping.has( viewNode ) ) {\n\t\t\treturn 1;\n\t\t} else if ( viewNode.is( 'text' ) ) {\n\t\t\treturn viewNode.data.length;\n\t\t} else if ( viewNode.is( 'uiElement' ) ) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\tlet len = 0;\n\n\t\t\tfor ( const child of viewNode.getChildren() ) {\n\t\t\t\tlen += this.getModelLength( child );\n\t\t\t}\n\n\t\t\treturn len;\n\t\t}\n\t}\n\n\t/**\n\t * Finds the position in the view node (or its children) with the expected model offset.\n\t *\n\t * Example:\n\t *\n\t *\t\t<p>fo<b>bar</b>bom</p> -> expected offset: 4\n\t *\n\t *\t\t_findPositionIn( p, 4 ):\n\t *\t\t<p>|fo<b>bar</b>bom</p> -> expected offset: 4, actual offset: 0\n\t *\t\t<p>fo|<b>bar</b>bom</p> -> expected offset: 4, actual offset: 2\n\t *\t\t<p>fo<b>bar</b>|bom</p> -> expected offset: 4, actual offset: 5 -> we are too far\n\t *\n\t *\t\t_findPositionIn( b, 4 - ( 5 - 3 ) ):\n\t *\t\t<p>fo<b>|bar</b>bom</p> -> expected offset: 2, actual offset: 0\n\t *\t\t<p>fo<b>bar|</b>bom</p> -> expected offset: 2, actual offset: 3 -> we are too far\n\t *\n\t *\t\t_findPositionIn( bar, 2 - ( 3 - 3 ) ):\n\t *\t\tWe are in the text node so we can simple find the offset.\n\t *\t\t<p>fo<b>ba|r</b>bom</p> -> expected offset: 2, actual offset: 2 -> position found\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} viewParent Tree view element in which we are looking for the position.\n\t * @param {Number} expectedOffset Expected offset.\n\t * @returns {module:engine/view/position~Position} Found position.\n\t */\n\t_findPositionIn( viewParent, expectedOffset ) {\n\t\t// Last scanned view node.\n\t\tlet viewNode;\n\t\t// Length of the last scanned view node.\n\t\tlet lastLength = 0;\n\n\t\tlet modelOffset = 0;\n\t\tlet viewOffset = 0;\n\n\t\t// In the text node it is simple: offset in the model equals offset in the text.\n\t\tif ( viewParent.is( 'text' ) ) {\n\t\t\treturn new ViewPosition( viewParent, expectedOffset );\n\t\t}\n\n\t\t// In other cases we add lengths of child nodes to find the proper offset.\n\n\t\t// If it is smaller we add the length.\n\t\twhile ( modelOffset < expectedOffset ) {\n\t\t\tviewNode = viewParent.getChild( viewOffset );\n\t\t\tlastLength = this.getModelLength( viewNode );\n\t\t\tmodelOffset += lastLength;\n\t\t\tviewOffset++;\n\t\t}\n\n\t\t// If it equals we found the position.\n\t\tif ( modelOffset == expectedOffset ) {\n\t\t\treturn this._moveViewPositionToTextNode( new ViewPosition( viewParent, viewOffset ) );\n\t\t}\n\t\t// If it is higher we need to enter last child.\n\t\telse {\n\t\t\t// ( modelOffset - lastLength ) is the offset to the child we enter,\n\t\t\t// so we subtract it from the expected offset to fine the offset in the child.\n\t\t\treturn this._findPositionIn( viewNode, expectedOffset - ( modelOffset - lastLength ) );\n\t\t}\n\t}\n\n\t/**\n\t * Because we prefer positions in text nodes over positions next to text node moves view position to the text node\n\t * if it was next to it.\n\t *\n\t *\t\t<p>[]<b>foo</b></p> -> <p>[]<b>foo</b></p> // do not touch if position is not directly next to text\n\t *\t\t<p>foo[]<b>foo</b></p> -> <p>foo{}<b>foo</b></p> // move to text node\n\t *\t\t<p><b>[]foo</b></p> -> <p><b>{}foo</b></p> // move to text node\n\t *\n\t * @private\n\t * @param {module:engine/view/position~Position} viewPosition Position potentially next to text node.\n\t * @returns {module:engine/view/position~Position} Position in text node if possible.\n\t */\n\t_moveViewPositionToTextNode( viewPosition ) {\n\t\t// If the position is just after text node, put it at the end of that text node.\n\t\t// If the position is just before text node, put it at the beginning of that text node.\n\t\tconst nodeBefore = viewPosition.nodeBefore;\n\t\tconst nodeAfter = viewPosition.nodeAfter;\n\n\t\tif ( nodeBefore instanceof ViewText ) {\n\t\t\treturn new ViewPosition( nodeBefore, nodeBefore.data.length );\n\t\t} else if ( nodeAfter instanceof ViewText ) {\n\t\t\treturn new ViewPosition( nodeAfter, 0 );\n\t\t}\n\n\t\t// Otherwise, just return the given position.\n\t\treturn viewPosition;\n\t}\n\n\t/**\n\t * Fired for each model-to-view position mapping request. The purpose of this event is to enable custom model-to-view position\n\t * mapping. Callbacks added to this event take {@link module:engine/model/position~Position model position} and are expected to\n\t * calculate {@link module:engine/view/position~Position view position}. Calculated view position should be added as `viewPosition`\n\t * value in `data` object that is passed as one of parameters to the event callback.\n\t *\n\t * \t\t// Assume that \"captionedImage\" model element is converted to <img> and following <span> elements in view,\n\t * \t\t// and the model element is bound to <img> element. Force mapping model positions inside \"captionedImage\" to that\n\t * \t\t// <span> element.\n\t *\t\tmapper.on( 'modelToViewPosition', ( evt, data ) => {\n\t *\t\t\tconst positionParent = modelPosition.parent;\n\t *\n\t *\t\t\tif ( positionParent.name == 'captionedImage' ) {\n\t *\t\t\t\tconst viewImg = data.mapper.toViewElement( positionParent );\n\t *\t\t\t\tconst viewCaption = viewImg.nextSibling; // The <span> element.\n\t *\n\t *\t\t\t\tdata.viewPosition = new ViewPosition( viewCaption, modelPosition.offset );\n\t *\n\t *\t\t\t\t// Stop the event if other callbacks should not modify calculated value.\n\t *\t\t\t\tevt.stop();\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * **Note:** keep in mind that custom callback provided for this event should use provided `data.modelPosition` only to check\n\t * what is before the position (or position's parent). This is important when model-to-view position mapping is used in\n\t * remove change conversion. Model after the removed position (that is being mapped) does not correspond to view, so it cannot be used:\n\t *\n\t *\t\t// Incorrect:\n\t *\t\tconst modelElement = data.modelPosition.nodeAfter;\n\t *\t\tconst viewElement = data.mapper.toViewElement( modelElement );\n\t *\t\t// ... Do something with `viewElement` and set `data.viewPosition`.\n\t *\n\t *\t\t// Correct:\n\t *\t\tconst prevModelElement = data.modelPosition.nodeBefore;\n\t *\t\tconst prevViewElement = data.mapper.toViewElement( prevModelElement );\n\t *\t\t// ... Use `prevViewElement` to find correct `data.viewPosition`.\n\t *\n\t * **Note:** default mapping callback is provided with `low` priority setting and does not cancel the event, so it is possible to\n\t * attach a custom callback after default callback and also use `data.viewPosition` calculated by default callback\n\t * (for example to fix it).\n\t *\n\t * **Note:** default mapping callback will not fire if `data.viewPosition` is already set.\n\t *\n\t * **Note:** these callbacks are called **very often**. For efficiency reasons, it is advised to use them only when position\n\t * mapping between given model and view elements is unsolvable using just elements mapping and default algorithm. Also,\n\t * the condition that checks if special case scenario happened should be as simple as possible.\n\t *\n\t * @event modelToViewPosition\n\t * @param {Object} data Data pipeline object that can store and pass data between callbacks. The callback should add\n\t * `viewPosition` value to that object with calculated {@link module:engine/view/position~Position view position}.\n\t * @param {module:engine/conversion/mapper~Mapper} data.mapper Mapper instance that fired the event.\n\t */\n\n\t/**\n\t * Fired for each view-to-model position mapping request. See {@link module:engine/conversion/mapper~Mapper#event:modelToViewPosition}.\n\t *\n\t * \t\t// See example in `modelToViewPosition` event description.\n\t * \t\t// This custom mapping will map positions from <span> element next to <img> to the \"captionedImage\" element.\n\t *\t\tmapper.on( 'viewToModelPosition', ( evt, data ) => {\n\t *\t\t\tconst positionParent = viewPosition.parent;\n\t *\n\t *\t\t\tif ( positionParent.hasClass( 'image-caption' ) ) {\n\t *\t\t\t\tconst viewImg = positionParent.previousSibling;\n\t *\t\t\t\tconst modelImg = data.mapper.toModelElement( viewImg );\n\t *\n\t *\t\t\t\tdata.modelPosition = new ModelPosition( modelImg, viewPosition.offset );\n\t *\t\t\t\tevt.stop();\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * **Note:** default mapping callback is provided with `low` priority setting and does not cancel the event, so it is possible to\n\t * attach a custom callback after default callback and also use `data.modelPosition` calculated by default callback\n\t * (for example to fix it).\n\t *\n\t * **Note:** default mapping callback will not fire if `data.modelPosition` is already set.\n\t *\n\t * **Note:** these callbacks are called **very often**. For efficiency reasons, it is advised to use them only when position\n\t * mapping between given model and view elements is unsolvable using just elements mapping and default algorithm. Also,\n\t * the condition that checks if special case scenario happened should be as simple as possible.\n\t *\n\t * @event viewToModelPosition\n\t * @param {Object} data Data pipeline object that can store and pass data between callbacks. The callback should add\n\t * `modelPosition` value to that object with calculated {@link module:engine/model/position~Position model position}.\n\t * @param {module:engine/conversion/mapper~Mapper} data.mapper Mapper instance that fired the event.\n\t */\n}\n\nmix( Mapper, EmitterMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/mapper.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module module:engine/model/documentfragment\n */\n\nimport NodeList from './nodelist';\nimport Element from './element';\nimport Text from './text';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * DocumentFragment represents a part of model which does not have a common root but it's 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 * DocumentFragment has own {@link module:engine/model/markercollection~MarkerCollection}. Markers from this collection\n * will be set to the {@link module:engine/model/document~Document#markers document markers} by a\n * {@link module:engine/model/writer~writer.insert} function.\n */\nexport default class DocumentFragment {\n\t/**\n\t * Creates an empty `DocumentFragment`.\n\t *\n\t * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} [children]\n\t * Nodes to be contained inside the `DocumentFragment`.\n\t */\n\tconstructor( children ) {\n\t\t/**\n\t\t * DocumentFragment static markers map. This is a list of names and {@link module:engine/model/range~Range ranges}\n\t\t * which will be set as Markers to {@link module:engine/model/document~Document#markers document markers collection}\n\t\t * when DocumentFragment will be inserted to the document.\n\t\t *\n\t\t * @member {Map<String, {module:engine/model/range~Range}>} module:engine/model/documentfragment~DocumentFragment#markers\n\t\t */\n\t\tthis.markers = new Map();\n\n\t\t/**\n\t\t * List of nodes contained inside the document fragment.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/nodelist~NodeList} module:engine/model/documentfragment~DocumentFragment#_children\n\t\t */\n\t\tthis._children = new NodeList();\n\n\t\tif ( children ) {\n\t\t\tthis.insertChildren( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all nodes contained inside this document fragment.\n\t *\n\t * @returns {Iterator.<module:engine/model/node~Node>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this.getChildren();\n\t}\n\n\t/**\n\t * Number of this document fragment's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Sum of {module:engine/model/node~Node#offsetSize offset sizes} of all of this document fragment's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget maxOffset() {\n\t\treturn this._children.maxOffset;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t *\n\t * @readonly\n\t * @type {null}\n\t */\n\tget parent() {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether given model tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/model/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'documentFragment';\n\t}\n\n\t/**\n\t * Gets the child at the given index. Returns `null` if incorrect index was passed.\n\t *\n\t * @param {Number} index Index of child.\n\t * @returns {module:engine/model/node~Node|null} Child node.\n\t */\n\tgetChild( index ) {\n\t\treturn this._children.getNode( index );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all of this document fragment's children.\n\t *\n\t * @returns {Iterable.<module:engine/model/node~Node>}\n\t */\n\tgetChildren() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\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 {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number|null} Child node's index.\n\t */\n\tgetChildIndex( node ) {\n\t\treturn this._children.getNodeIndex( node );\n\t}\n\n\t/**\n\t * Returns the starting offset of given child. Starting offset is equal to the sum of\n\t * {module:engine/model/node~Node#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 {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number|null} Child node's starting offset.\n\t */\n\tgetChildStartOffset( node ) {\n\t\treturn this._children.getNodeStartOffset( node );\n\t}\n\n\t/**\n\t * Returns path to a `DocumentFragment`, which is an empty array. Added for compatibility reasons.\n\t *\n\t * @returns {Array}\n\t */\n\tgetPath() {\n\t\treturn [];\n\t}\n\n\t/**\n\t * Returns a descendant node by its path relative to this element.\n\t *\n\t *\t\t// <this>a<b>c</b></this>\n\t *\t\tthis.getNodeByPath( [ 0 ] ); // -> \"a\"\n\t *\t\tthis.getNodeByPath( [ 1 ] ); // -> <b>\n\t *\t\tthis.getNodeByPath( [ 1, 0 ] ); // -> \"c\"\n\t *\n\t * @param {Array.<Number>} relativePath Path of the node to find, relative to this element.\n\t * @returns {module:engine/model/node~Node|module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tgetNodeByPath( relativePath ) {\n\t\tlet node = this; // eslint-disable-line consistent-this\n\n\t\tfor ( const index of relativePath ) {\n\t\t\tnode = node.getChild( node.offsetToIndex( index ) );\n\t\t}\n\n\t\treturn node;\n\t}\n\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 *\t\tconst textNode = new Text( 'foo' );\n\t *\t\tconst pElement = new Element( 'p' );\n\t *\t\tconst docFrag = new DocumentFragment( [ textNode, pElement ] );\n\t *\t\tdocFrag.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t *\t\tdocFrag.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t *\t\tdocFrag.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t *\t\tdocFrag.offsetToIndex( 2 ); // Returns 0.\n\t *\t\tdocFrag.offsetToIndex( 3 ); // Returns 1.\n\t *\t\tdocFrag.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t *\n\t * @param {Number} offset Offset to look for.\n\t * @returns {Number} Index of a node that occupies given offset.\n\t */\n\toffsetToIndex( offset ) {\n\t\treturn this._children.offsetToIndex( offset );\n\t}\n\n\t/**\n\t * {@link #insertChildren Inserts} one or more nodes at the end of this document fragment.\n\t *\n\t * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} nodes Nodes to be inserted.\n\t */\n\tappendChildren( nodes ) {\n\t\tthis.insertChildren( this.childCount, nodes );\n\t}\n\n\t/**\n\t * Inserts one or more nodes at the given index and sets {@link module:engine/model/node~Node#parent parent} of these nodes\n\t * to this document fragment.\n\t *\n\t * @param {Number} index Index at which nodes should be inserted.\n\t * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} nodes Nodes to be inserted.\n\t */\n\tinsertChildren( index, nodes ) {\n\t\tnodes = normalize( nodes );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode.remove();\n\t\t\t}\n\n\t\t\tnode.parent = this;\n\t\t}\n\n\t\tthis._children.insertNodes( index, nodes );\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index\n\t * and sets {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.\n\t *\n\t * @param {Number} index Index of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/model/node~Node>} Array containing removed nodes.\n\t */\n\tremoveChildren( index, howMany = 1 ) {\n\t\tconst nodes = this._children.removeNodes( index, howMany );\n\n\t\tfor ( const node of nodes ) {\n\t\t\tnode.parent = null;\n\t\t}\n\n\t\treturn nodes;\n\t}\n\n\t/**\n\t * Converts `DocumentFragment` 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 {Object} `DocumentFragment` instance converted to plain object.\n\t */\n\ttoJSON() {\n\t\tconst json = [];\n\n\t\tfor ( const node of this._children ) {\n\t\t\tjson.push( node.toJSON() );\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a `DocumentFragment` instance from given plain object (i.e. parsed JSON string).\n\t * Converts `DocumentFragment` children to proper nodes.\n\t *\n\t * @param {Object} json Plain object to be converted to `DocumentFragment`.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} `DocumentFragment` instance created using given plain object.\n\t */\n\tstatic fromJSON( json ) {\n\t\tconst children = [];\n\n\t\tfor ( const child of json ) {\n\t\t\tif ( child.name ) {\n\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t} else {\n\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t}\n\t\t}\n\n\t\treturn new DocumentFragment( children );\n\t}\n}\n\n// Converts strings to Text and non-iterables to arrays.\n//\n// @param {String|module:engine/model/node~Node|Iterable.<String|module:engine/model/node~Node>}\n// @return {Iterable.<module:engine/model/node~Node>}\nfunction normalize( nodes ) {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\treturn typeof node == 'string' ? new Text( node ) : node;\n\t\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/documentfragment.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/modelconversiondispatcher\n */\n\nimport Consumable from './modelconsumable';\nimport Range from '../model/range';\nimport Position from '../model/position';\nimport DocumentFragment from '../model/documentfragment';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport extend from '@ckeditor/ckeditor5-utils/src/lib/lodash/extend';\n\n/**\n * `ModelConversionDispatcher` is a central point of {@link module:engine/model/model model} conversion, which is\n * a process of reacting to changes in the model and reflecting them by listeners that listen to those changes.\n * In default application, {@link module:engine/model/model model} is converted to {@link module:engine/view/view view}. This means\n * that changes in the model are reflected by changing the view (i.e. adding view nodes or changing attributes on view elements).\n *\n * During conversion process, `ModelConversionDispatcher` fires data-manipulation events, basing on state of the model and prepares\n * data for those events. It is important to note that the events are connected with \"change actions\" like \"inserting\"\n * or \"removing\" so one might say that we are converting \"changes\". This is in contrary to view to model conversion,\n * where we convert view nodes (the structure, not \"changes\" to the view). Note, that because changes are converted\n * and not the structure itself, there is a need to have a mapping between model and the structure on which changes are\n * reflected. To map elements during model to view conversion use {@link module:engine/conversion/mapper~Mapper}.\n *\n * The main use for this class is to listen to {@link module:engine/model/document~Document#event:change Document change event}, process it\n * and then fire specific events telling what exactly has changed. For those events, `ModelConversionDispatcher`\n * creates {@link module:engine/conversion/modelconsumable~ModelConsumable list of consumable values} that should be handled by event\n * callbacks. Those events are listened to by model-to-view converters which convert changes done in the\n * {@link module:engine/model/model model} to changes in the {@link module:engine/view/view view}. `ModelConversionController` also checks\n * the current state of consumables, so it won't fire events for parts of model that were already consumed. This is\n * especially important in callbacks that consume multiple values. See {@link module:engine/conversion/modelconsumable~ModelConsumable}\n * for an example of such callback.\n *\n * Although the primary usage for this class is the model-to-view conversion, `ModelConversionDispatcher` can be used\n * to build custom data processing pipelines that converts model to anything that is needed. Existing model structure can\n * be used to generate events (listening to {@link module:engine/model/document~Document#event:change Document change event} is not\n * required)\n * and custom callbacks can be added to the events (these does not have to be limited to changes in the view).\n *\n * When providing your own event listeners for `ModelConversionDispatcher` keep in mind that any callback that had\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} a value from consumable (and did some changes, i.e. to\n * the view) should also stop the event. This is because whenever a callback is fired it is assumed that there is something\n * to be consumed. Thanks to that approach, you do not have to test whether there is anything to consume at the beginning\n * of your listener callback.\n *\n * Example of providing a converter for `ModelConversionDispatcher`:\n *\n *\t\t// We will convert inserting \"paragraph\" model element into the model.\n *\t\tmodelDispatcher.on( 'insert:paragraph', ( evt, data, consumable, conversionApi ) => {\n *\t\t\t// Remember to consume the part of consumable.\n *\t\t\tconsumable.consume( data.item, 'insert' );\n *\n *\t\t\t// Translate position in model to position in the view.\n *\t\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n *\n *\t\t\t// Create a P element (note that this converter is for inserting P elements -> 'insert:paragraph').\n *\t\t\tconst viewElement = new ViewElement( 'p' );\n *\n *\t\t\t// Bind the newly created view element to model element so positions will map accordingly in future.\n *\t\t\tconversionApi.mapper.bindElements( data.item, viewElement );\n *\n *\t\t\t// Add the newly created view element to the view.\n *\t\t\tviewWriter.insert( viewPosition, viewElement );\n *\n *\t\t\t// Remember to stop the event propagation if the data.item was consumed.\n *\t\t\tevt.stop();\n *\t\t} );\n *\n * Callback that \"overrides\" other callback:\n *\n *\t\t// Special converter for `linkHref` attribute added on custom `quote` element. Note, that this\n *\t\t// attribute may be the same as the attribute added by other features (link feature in this case).\n *\t\t// It might be even added by that feature! It makes sense that a part of content that is a quote is linked\n *\t\t// to an external source so it makes sense that link feature works on the custom quote element.\n *\t\t// However, we have to make sure that the attributes added by link feature are correctly converted.\n *\t\t// To block default `linkHref` conversion we have to:\n *\t\t// 1) add this callback with higher priority than link feature callback,\n *\t\t// 2) consume `linkHref` attribute add change.\n *\t\tmodelConversionDispatcher.on( 'addAttribute:linkHref:quote', ( evt, data, consumable, conversionApi ) => {\n *\t\t\tconsumable.consume( data.item, 'addAttribute:linkHref' );\n *\n *\t\t\t// Create a button that will represent the `linkHref` attribute.\n *\t\t\tlet viewSourceBtn = new ViewElement( 'a', {\n *\t\t\t\thref: data.item.getAttribute( 'linkHref' ),\n *\t\t\t\ttitle: 'source'\n *\t\t\t} );\n *\n *\t\t\t// Add a class for the button.\n *\t\t\tviewSourceBtn.addClass( 'source' );\n *\n *\t\t\t// Insert the button using writer API.\n *\t\t\t// If `addAttribute` event is fired by\n *\t\t\t// `module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#convertInsert` it is fired\n *\t\t\t// after `data.item` insert conversion was done. If the event is fired due to attribute insertion coming from\n *\t\t\t// different source, `data.item` already existed. This means we are safe to get `viewQuote` from mapper.\n *\t\t\tconst viewQuote = conversionApi.mapper.toViewElement( data.item );\n *\t\t\tconst position = new ViewPosition( viewQuote, viewQuote.childCount );\n *\t\t\tviewWriter.insert( position, viewSourceBtn );\n *\n *\t\t\tevt.stop();\n *\t\t}, { priority: 'high' } );\n */\nexport default class ModelConversionDispatcher {\n\t/**\n\t * Creates a `ModelConversionDispatcher` that operates using passed API.\n\t *\n\t * @param {module:engine/model/document~Document} modelDocument Model document instance bound with this dispatcher.\n\t * @param {Object} [conversionApi] Interface passed by dispatcher to the events callbacks.\n\t */\n\tconstructor( modelDocument, conversionApi = {} ) {\n\t\t/**\n\t\t * Model document instance bound with this dispatcher.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/document~Document}\n\t\t */\n\t\tthis._modelDocument = modelDocument;\n\n\t\t/**\n\t\t * Interface passed by dispatcher to the events callbacks.\n\t\t *\n\t\t * @member {Object}\n\t\t */\n\t\tthis.conversionApi = extend( { dispatcher: this }, conversionApi );\n\t}\n\n\t/**\n\t * Prepares data and fires a proper event.\n\t *\n\t * The method is crafted to take use of parameters passed in {@link module:engine/model/document~Document#event:change Document change\n\t * event}.\n\t *\n\t * @see module:engine/model/document~Document#event:change\n\t * @fires insert\n\t * @fires remove\n\t * @fires addAttribute\n\t * @fires removeAttribute\n\t * @fires changeAttribute\n\t * @fires addMarker\n\t * @param {String} type Change type.\n\t * @param {Object} data Additional information about the change.\n\t */\n\tconvertChange( type, data ) {\n\t\t// Do not convert changes if they happen in graveyard.\n\t\t// Graveyard is a special root that has no view / no other representation and changes done in it should not be converted.\n\t\tif ( type !== 'remove' && data.range && data.range.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type == 'remove' && data.sourcePosition.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type == 'rename' && data.element.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We can safely dispatch changes.\n\t\tif ( type == 'insert' || type == 'reinsert' ) {\n\t\t\tthis.convertInsertion( data.range );\n\t\t} else if ( type == 'move' ) {\n\t\t\tthis.convertMove( data.sourcePosition, data.range );\n\t\t} else if ( type == 'remove' ) {\n\t\t\tthis.convertRemove( data.sourcePosition, data.range );\n\t\t} else if ( type == 'addAttribute' || type == 'removeAttribute' || type == 'changeAttribute' ) {\n\t\t\tthis.convertAttribute( type, data.range, data.key, data.oldValue, data.newValue );\n\t\t} else if ( type == 'rename' ) {\n\t\t\tthis.convertRename( data.element, data.oldName );\n\t\t}\n\t}\n\n\t/**\n\t * Starts conversion of insertion-change on given `range`.\n\t *\n\t * Analyzes given range and fires insertion-connected events with data based on that range.\n\t *\n\t * **Note**: This method will fire separate events for node insertion and attributes insertion. All\n\t * attributes that are set on inserted nodes are treated like they were added just after node insertion.\n\t *\n\t * @fires insert\n\t * @fires addAttribute\n\t * @fires addMarker\n\t * @param {module:engine/model/range~Range} range Inserted range.\n\t */\n\tconvertInsertion( range ) {\n\t\t// Create a list of things that can be consumed, consisting of nodes and their attributes.\n\t\tconst consumable = this._createInsertConsumable( range );\n\n\t\t// Fire a separate insert event for each node and text fragment contained in the range.\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\t\t\tconst itemRange = Range.createFromPositionAndShift( value.previousPosition, value.length );\n\t\t\tconst data = {\n\t\t\t\titem,\n\t\t\t\trange: itemRange\n\t\t\t};\n\n\t\t\tthis._testAndFire( 'insert', data, consumable );\n\n\t\t\t// Fire a separate addAttribute event for each attribute that was set on inserted items.\n\t\t\t// This is important because most attributes converters will listen only to add/change/removeAttribute events.\n\t\t\t// If we would not add this part, attributes on inserted nodes would not be converted.\n\t\t\tfor ( const key of item.getAttributeKeys() ) {\n\t\t\t\tdata.attributeKey = key;\n\t\t\t\tdata.attributeOldValue = null;\n\t\t\t\tdata.attributeNewValue = item.getAttribute( key );\n\n\t\t\t\tthis._testAndFire( `addAttribute:${ key }`, data, consumable );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const marker of this._modelDocument.markers ) {\n\t\t\tconst markerRange = marker.getRange();\n\t\t\tconst intersection = markerRange.getIntersection( range );\n\n\t\t\t// Check if inserted content is inserted into a marker.\n\t\t\tif ( intersection && shouldMarkerChangeBeConverted( range.start, marker, this.conversionApi.mapper ) ) {\n\t\t\t\tthis.convertMarker( 'addMarker', marker.name, intersection );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Starts conversion of move-change of given `range`, that was moved from given `sourcePosition`.\n\t *\n\t * Fires {@link ~#event:remove remove event} and {@link ~#event:insert insert event} based on passed parameters.\n\t *\n\t * @fires remove\n\t * @fires insert\n\t * @param {module:engine/model/position~Position} sourcePosition The original position from which the range was moved.\n\t * @param {module:engine/model/range~Range} range The range containing the moved content.\n\t */\n\tconvertMove( sourcePosition, range ) {\n\t\t// Move left convert insertion first (#847).\n\t\tif ( range.start.isBefore( sourcePosition ) ) {\n\t\t\tthis.convertInsertion( range );\n\n\t\t\tconst sourcePositionAfterInsertion =\n\t\t\t\tsourcePosition._getTransformedByInsertion( range.start, range.end.offset - range.start.offset );\n\n\t\t\tthis.convertRemove( sourcePositionAfterInsertion, range );\n\t\t} else {\n\t\t\tthis.convertRemove( sourcePosition, range );\n\t\t\tthis.convertInsertion( range );\n\t\t}\n\t}\n\n\t/**\n\t * Starts conversion of remove-change of given `range`, that was removed from given `sourcePosition`.\n\t *\n\t * Fires {@link ~#event:remove remove event} with data based on passed values.\n\t *\n\t * @fires remove\n\t * @param {module:engine/model/position~Position} sourcePosition Position from where the range has been removed.\n\t * @param {module:engine/model/range~Range} range Removed range (after remove, in\n\t * {@link module:engine/model/document~Document#graveyard graveyard root}).\n\t */\n\tconvertRemove( sourcePosition, range ) {\n\t\tconst consumable = this._createConsumableForRange( range, 'remove' );\n\n\t\tfor ( const item of range.getItems( { shallow: true } ) ) {\n\t\t\tconst data = {\n\t\t\t\tsourcePosition,\n\t\t\t\titem\n\t\t\t};\n\n\t\t\tthis._testAndFire( 'remove', data, consumable );\n\t\t}\n\t}\n\n\t/**\n\t * Starts conversion of attribute-change on given `range`.\n\t *\n\t * Analyzes given attribute change and fires attributes-connected events with data based on passed values.\n\t *\n\t * @fires addAttribute\n\t * @fires removeAttribute\n\t * @fires changeAttribute\n\t * @param {String} type Change type. Possible values: `addAttribute`, `removeAttribute`, `changeAttribute`.\n\t * @param {module:engine/model/range~Range} range Changed range.\n\t * @param {String} key Attribute key.\n\t * @param {*} oldValue Attribute value before the change or `null` if attribute has not been set.\n\t * @param {*} newValue New attribute value or `null` if attribute has been removed.\n\t */\n\tconvertAttribute( type, range, key, oldValue, newValue ) {\n\t\tif ( oldValue == newValue ) {\n\t\t\t// Do not convert if the attribute did not change.\n\t\t\treturn;\n\t\t}\n\n\t\t// Create a list with attributes to consume.\n\t\tconst consumable = this._createConsumableForRange( range, type + ':' + key );\n\n\t\t// Create a separate attribute event for each node in the range.\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\t\t\tconst itemRange = Range.createFromPositionAndShift( value.previousPosition, value.length );\n\t\t\tconst data = {\n\t\t\t\titem,\n\t\t\t\trange: itemRange,\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\tattributeNewValue: newValue\n\t\t\t};\n\n\t\t\tthis._testAndFire( `${ type }:${ key }`, data, consumable );\n\t\t}\n\t}\n\n\t/**\n\t * Starts conversion of rename-change of given `element` that had given `oldName`.\n\t *\n\t * Fires {@link ~#event:remove remove event} and {@link ~#event:insert insert event} based on passed values.\n\t *\n\t * @fires remove\n\t * @fires insert\n\t * @param {module:engine/model/element~Element} element Renamed element.\n\t * @param {String} oldName Name of the renamed element before it was renamed.\n\t */\n\tconvertRename( element, oldName ) {\n\t\tif ( element.name == oldName ) {\n\t\t\t// Do not convert if the name did not change.\n\t\t\treturn;\n\t\t}\n\n\t\t// Create fake element that will be used to fire remove event. The fake element will have the old element name.\n\t\tconst fakeElement = element.clone( true );\n\t\tfakeElement.name = oldName;\n\n\t\t// Bind fake element with original view element so the view element will be removed.\n\t\tthis.conversionApi.mapper.bindElements(\n\t\t\tfakeElement,\n\t\t\tthis.conversionApi.mapper.toViewElement( element )\n\t\t);\n\n\t\t// Create fake document fragment so a range can be created on fake element.\n\t\tconst fakeDocumentFragment = new DocumentFragment();\n\t\tfakeDocumentFragment.appendChildren( fakeElement );\n\n\t\tthis.convertRemove( Position.createBefore( element ), Range.createOn( fakeElement ) );\n\t\tthis.convertInsertion( Range.createOn( element ) );\n\t}\n\n\t/**\n\t * Starts selection conversion.\n\t *\n\t * Fires events for given {@link module:engine/model/selection~Selection selection} to start selection conversion.\n\t *\n\t * @fires selection\n\t * @fires selectionAttribute\n\t * @param {module:engine/model/selection~Selection} selection Selection to convert.\n\t */\n\tconvertSelection( selection ) {\n\t\tconst markers = Array.from( this._modelDocument.markers.getMarkersAtPosition( selection.getFirstPosition() ) );\n\t\tconst consumable = this._createSelectionConsumable( selection, markers );\n\n\t\tthis.fire( 'selection', { selection }, consumable, this.conversionApi );\n\n\t\tfor ( const marker of markers ) {\n\t\t\tconst markerRange = marker.getRange();\n\n\t\t\tif ( !shouldMarkerChangeBeConverted( selection.getFirstPosition(), marker, this.conversionApi.mapper ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst data = {\n\t\t\t\tselection,\n\t\t\t\tmarkerName: marker.name,\n\t\t\t\tmarkerRange\n\t\t\t};\n\n\t\t\tif ( consumable.test( selection, 'selectionMarker:' + marker.name ) ) {\n\t\t\t\tthis.fire( 'selectionMarker:' + marker.name, data, consumable, this.conversionApi );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const key of selection.getAttributeKeys() ) {\n\t\t\tconst data = {\n\t\t\t\tselection,\n\t\t\t\tkey,\n\t\t\t\tvalue: selection.getAttribute( key )\n\t\t\t};\n\n\t\t\t// Do not fire event if the attribute has been consumed.\n\t\t\tif ( consumable.test( selection, 'selectionAttribute:' + data.key ) ) {\n\t\t\t\tthis.fire( 'selectionAttribute:' + data.key, data, consumable, this.conversionApi );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Starts marker conversion.\n\t *\n\t * Fires {@link ~#event:addMarker addMarker} or {@link ~#event:removeMarker removeMarker} events for each item\n\t * in marker's range. If range is collapsed single event is dispatched. See events description for more details.\n\t *\n\t * @fires addMarker\n\t * @fires removeMarker\n\t * @param {'addMarker'|'removeMarker'} type Change type.\n\t * @param {String} name Marker name.\n\t * @param {module:engine/model/range~Range} range Marker range.\n\t */\n\tconvertMarker( type, name, range ) {\n\t\t// Do not convert if range is in graveyard or not in the document (e.g. in DocumentFragment).\n\t\tif ( !range.root.document || range.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// In markers case, event name == consumable name.\n\t\tconst eventName = type + ':' + name;\n\n\t\t// When range is collapsed - fire single event with collapsed range in consumable.\n\t\tif ( range.isCollapsed ) {\n\t\t\tconst consumable = new Consumable();\n\t\t\tconsumable.add( range, eventName );\n\n\t\t\tthis.fire( eventName, {\n\t\t\t\tmarkerName: name,\n\t\t\t\tmarkerRange: range\n\t\t\t}, consumable, this.conversionApi );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Create consumable for each item in range.\n\t\tconst consumable = this._createConsumableForRange( range, eventName );\n\n\t\t// Create separate event for each node in the range.\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\n\t\t\t// Do not fire event for already consumed items.\n\t\t\tif ( !consumable.test( item, eventName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst data = {\n\t\t\t\titem,\n\t\t\t\trange: Range.createFromPositionAndShift( value.previousPosition, value.length ),\n\t\t\t\tmarkerName: name,\n\t\t\t\tmarkerRange: range\n\t\t\t};\n\n\t\t\tthis.fire( eventName, data, consumable, this.conversionApi );\n\t\t}\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume from given range, assuming that\n\t * given range has just been inserted to the model.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range Inserted range.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} Values to consume.\n\t */\n\t_createInsertConsumable( range ) {\n\t\tconst consumable = new Consumable();\n\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\n\t\t\tconsumable.add( item, 'insert' );\n\n\t\t\tfor ( const key of item.getAttributeKeys() ) {\n\t\t\t\tconsumable.add( item, 'addAttribute:' + key );\n\t\t\t}\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with values of given `type`\n\t * for each item from given `range`.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range Affected range.\n\t * @param {String} type Consumable type.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} Values to consume.\n\t */\n\t_createConsumableForRange( range, type ) {\n\t\tconst consumable = new Consumable();\n\n\t\tfor ( const item of range.getItems() ) {\n\t\t\tconsumable.add( item, type );\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with selection consumable values.\n\t *\n\t * @private\n\t * @param {module:engine/model/selection~Selection} selection Selection to create consumable from.\n\t * @param {Iterable.<module:engine/model/markercollection~Marker>} markers Markers which contains selection.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} Values to consume.\n\t */\n\t_createSelectionConsumable( selection, markers ) {\n\t\tconst consumable = new Consumable();\n\n\t\tconsumable.add( selection, 'selection' );\n\n\t\tfor ( const marker of markers ) {\n\t\t\tconsumable.add( selection, 'selectionMarker:' + marker.name );\n\t\t}\n\n\t\tfor ( const key of selection.getAttributeKeys() ) {\n\t\t\tconsumable.add( selection, 'selectionAttribute:' + key );\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Tests passed `consumable` to check whether given event can be fired and if so, fires it.\n\t *\n\t * @private\n\t * @fires insert\n\t * @fires remove\n\t * @fires addAttribute\n\t * @fires removeAttribute\n\t * @fires changeAttribute\n\t * @param {String} type Event type.\n\t * @param {Object} data Event data.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t */\n\t_testAndFire( type, data, consumable ) {\n\t\tif ( !consumable.test( data.item, type ) ) {\n\t\t\t// Do not fire event if the item was consumed.\n\t\t\treturn;\n\t\t}\n\n\t\tconst name = data.item.name || '$text';\n\n\t\tthis.fire( type + ':' + name, data, consumable, this.conversionApi );\n\t}\n\n\t/**\n\t * Fired for inserted nodes.\n\t *\n\t * `insert` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `insert:<name>`. `name` is either `'$text'` when one or more characters has been inserted or\n\t * {@link module:engine/model/element~Element#name name} of inserted element.\n\t *\n\t * This way listeners can either listen to a general `insert` event or specific event (for example `insert:paragraph`).\n\t *\n\t * @event insert\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item} data.item Inserted item.\n\t * @param {module:engine/model/range~Range} data.range Range spanning over inserted item.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired for removed nodes.\n\t *\n\t * `remove` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `remove:<name>`. `name` is either `'$text'` when one or more characters has been removed or the\n\t * {@link module:engine/model/element~Element#name name} of removed element.\n\t *\n\t * This way listeners can either listen to a general `remove` event or specific event (for example `remove:paragraph`).\n\t *\n\t * @event remove\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/position~Position} data.sourcePosition Position from where the range has been removed.\n\t * @param {module:engine/model/range~Range} data.range Removed range (in {@link module:engine/model/document~Document#graveyard\n\t * graveyard root}).\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when attribute has been added on a node.\n\t *\n\t * `addAttribute` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `addAttribute:<attributeKey>:<name>`. `attributeKey` is the key of added attribute. `name` is either `'$text'`\n\t * if attribute was added on one or more characters, or the {@link module:engine/model/element~Element#name name} of\n\t * the element on which attribute was added.\n\t *\n\t * This way listeners can either listen to a general `addAttribute:bold` event or specific event\n\t * (for example `addAttribute:link:image`).\n\t *\n\t * @event addAttribute\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item} data.item Changed item.\n\t * @param {module:engine/model/range~Range} data.range Range spanning over changed item.\n\t * @param {String} data.attributeKey Attribute key.\n\t * @param {null} data.attributeOldValue Attribute value before the change - always `null`. Kept for the sake of unifying events.\n\t * @param {*} data.attributeNewValue New attribute value.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when attribute has been removed from a node.\n\t *\n\t * `removeAttribute` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `removeAttribute:<attributeKey>:<name>`. `attributeKey` is the key of removed attribute. `name` is either `'$text'`\n\t * if attribute was removed from one or more characters, or the {@link module:engine/model/element~Element#name name} of\n\t * the element from which attribute was removed.\n\t *\n\t * This way listeners can either listen to a general `removeAttribute:bold` event or specific event\n\t * (for example `removeAttribute:link:image`).\n\t *\n\t * @event removeAttribute\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item} data.item Changed item.\n\t * @param {module:engine/model/range~Range} data.range Range spanning over changed item.\n\t * @param {String} data.attributeKey Attribute key.\n\t * @param {*} data.attributeOldValue Attribute value before it was removed.\n\t * @param {null} data.attributeNewValue New attribute value - always `null`. Kept for the sake of unifying events.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when attribute of a node has been changed.\n\t *\n\t * `changeAttribute` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `changeAttribute:<attributeKey>:<name>`. `attributeKey` is the key of changed attribute. `name` is either `'$text'`\n\t * if attribute was changed on one or more characters, or the {@link module:engine/model/element~Element#name name} of\n\t * the element on which attribute was changed.\n\t *\n\t * This way listeners can either listen to a general `changeAttribute:link` event or specific event\n\t * (for example `changeAttribute:link:image`).\n\t *\n\t * @event changeAttribute\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item} data.item Changed item.\n\t * @param {module:engine/model/range~Range} data.range Range spanning over changed item.\n\t * @param {String} data.attributeKey Attribute key.\n\t * @param {*} data.attributeOldValue Attribute value before the change.\n\t * @param {*} data.attributeNewValue New attribute value.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired for {@link module:engine/model/selection~Selection selection} changes.\n\t *\n\t * @event selection\n\t * @param {module:engine/model/selection~Selection} selection `Selection` instance that is converted.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired for {@link module:engine/model/selection~Selection selection} attributes changes.\n\t *\n\t * `selectionAttribute` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `selectionAttribute:<attributeKey>`. `attributeKey` is the key of selection attribute. This way listen can listen to\n\t * certain attribute, i.e. `addAttribute:bold`.\n\t *\n\t * @event selectionAttribute\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/selection~Selection} data.selection Selection that is converted.\n\t * @param {String} data.attributeKey Key of changed attribute.\n\t * @param {*} data.attributeValue Value of changed attribute.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when a new marker is added to the model.\n\t * * If marker's range is not collapsed, event is fired separately for each item contained in that range. In this\n\t * situation, consumable contains all items from that range.\n\t * * If marker's range is collapsed, single event is fired. In this situation, consumable contains only the collapsed range.\n\t *\n\t * `addMarker` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `addMarker:<markerName>`. By specifying certain marker names, you can make the events even more gradual. For example,\n\t * markers can be named `foo:abc`, `foo:bar`, then it is possible to listen to `addMarker:foo` or `addMarker:foo:abc` and\n\t * `addMarker:foo:bar` events.\n\t *\n\t * @event addMarker\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item} [data.item] Item contained in marker's range. Not present if collapsed range\n\t * is being converted.\n\t * @param {module:engine/model/range~Range} [data.range] Range spanning over item. Not present if collapsed range\n\t * is being converted.\n\t * @param {String} data.markerName Name of the marker.\n\t * @param {module:engine/model/range~Range} data.markerRange Marker's range spanning on all items.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume. When non-collapsed\n\t * marker is being converted then consumable contains all items in marker's range. For collapsed markers it contains\n\t * only marker's range to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when marker is removed from the model.\n\t * * If marker's range is not collapsed, event is fired separately for each item contained in that range. In this\n\t * situation, consumable contains all items from that range.\n\t * * If marker's range is collapsed, single event is fired. In this situation, consumable contains only the collapsed range.\n\t *\n\t * `removeMarker` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `removeMarker:<markerName>`. By specifying certain marker names, you can make the events even more gradual. For example,\n\t * markers can be named `foo:abc`, `foo:bar`, then it is possible to listen to `removeMarker:foo` or `removeMarker:foo:abc` and\n\t * `removeMarker:foo:bar` events.\n\t *\n\t * @event removeMarker\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item} [data.item] Item contained in marker's range. Not present if collapsed range\n\t * is being converted.\n\t * @param {module:engine/model/range~Range} [data.range] Range spanning over item. Not present if collapsed range\n\t * is being converted.\n\t * @param {String} data.markerName Name of the marker.\n\t * @param {module:engine/model/range~Range} data.markerRange Whole marker's range.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume. When non-collapsed\n\t * marker is being converted then consumable contains all items in marker's range. For collapsed markers it contains\n\t * only marker's range to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ModelConversionDispatcher` constructor.\n\t */\n}\n\nmix( ModelConversionDispatcher, EmitterMixin );\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//\n// @param {module:engine/model/position~Position} modelPosition\n// @param {module:engine/model/markercollection~Marker} marker\n// @param {module:engine/conversion/mapper~Mapper} mapper\n// @returns {Boolean}\nfunction shouldMarkerChangeBeConverted( modelPosition, marker, mapper ) {\n\tconst range = marker.getRange();\n\tconst ancestors = Array.from( modelPosition.getAncestors() );\n\tancestors.shift(); // Remove root element. It cannot be passed to `model.Range#containsItem`.\n\tancestors.reverse();\n\n\tconst hasCustomHandling = ancestors.some( element => {\n\t\tif ( range.containsItem( element ) ) {\n\t\t\tconst viewElement = mapper.toViewElement( element );\n\n\t\t\treturn !!viewElement.getCustomProperty( 'addHighlight' );\n\t\t}\n\t} );\n\n\treturn !hasCustomHandling;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/modelconversiondispatcher.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/attributeelement\n */\n\nimport Element from './element';\n\n// Default attribute priority.\nconst DEFAULT_PRIORITY = 10;\n\n/**\n * Attributes are elements which define document presentation. They are mostly elements like `<b>` or `<span>`.\n * Attributes can be broken and merged by the {@link module:engine/view/writer~writer view writer}.\n *\n * Editing engine does not define fixed HTML DTD. This is why the type of the {@link module:engine/view/element~Element} need to\n * be defined by the feature developer. Creating an element you should use {@link module:engine/view/containerelement~ContainerElement}\n * class or `AttributeElement`.\n *\n * @extends module:engine/view/element~Element\n */\nexport default class AttributeElement extends Element {\n\t/**\n\t * Creates a attribute element.\n\t *\n\t * @see module:engine/view/element~Element\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper( name, attrs, children );\n\n\t\t/**\n\t\t * Element priority. Attributes have to have the same priority to be\n\t\t * {@link module:engine/view/element~Element#isSimilar similar}. Setting different priorities on similar\n \t\t * nodes may prevent merging, e.g. two `<abbr>` nodes next each other shouldn't be merged.\n\t\t *\n\t\t * @member {Number}\n\t\t */\n\t\tthis.priority = DEFAULT_PRIORITY;\n\n\t\t/**\n\t\t * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {Number|null} Block filler offset or `null` if block filler is not needed.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'attributeElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'attributeElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\t/**\n\t * Clones provided element with priority.\n\t *\n\t * @param {Boolean} 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 {module:engine/view/attributeelement~AttributeElement} Clone of this element.\n\t */\n\tclone( deep ) {\n\t\tconst cloned = super.clone( deep );\n\n\t\t// Clone priority too.\n\t\tcloned.priority = this.priority;\n\n\t\treturn cloned;\n\t}\n\n\t/**\n\t * Checks if this element is similar to other element.\n\t * Both elements should have the same name, attributes and priority to be considered as similar.\n\t * Two similar elements can contain different set of children nodes.\n\t *\n\t * @param {module:engine/view/element~Element} otherElement\n\t * @returns {Boolean}\n\t */\n\tisSimilar( otherElement ) {\n\t\treturn super.isSimilar( otherElement ) && this.priority == otherElement.priority;\n\t}\n}\n\n/**\n * Default attribute priority.\n *\n * @member {Number} module:engine/view/attributeelement~AttributeElement.DEFAULT_PRIORITY\n */\nAttributeElement.DEFAULT_PRIORITY = DEFAULT_PRIORITY;\n\n// Returns block {@link module:engine/view/filler~Filler filler} offset or `null` if block filler is not needed.\n//\n// @returns {Number|null} Block filler offset or `null` if block filler is not needed.\nfunction getFillerOffset() {\n\t// <b>foo</b> does not need filler.\n\tif ( nonUiChildrenCount( this ) ) {\n\t\treturn null;\n\t}\n\n\tlet element = this.parent;\n\n\t// <p><b></b></p> needs filler -> <p><b><br></b></p>\n\twhile ( element && element.is( 'attributeElement' ) ) {\n\t\tif ( nonUiChildrenCount( element ) > 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\telement = element.parent;\n\t}\n\n\tif ( !element || nonUiChildrenCount( element ) > 1 ) {\n\t\treturn null;\n\t}\n\n\t// Render block filler at the end of element (after all ui elements).\n\treturn this.childCount;\n}\n\n// Returns total count of children that are not {@link module:engine/view/uielement~UIElement UIElements}.\n//\n// @param {module:engine/view/element~Element} element\n// @return {Number}\nfunction nonUiChildrenCount( element ) {\n\treturn Array.from( element.getChildren() ).filter( element => !element.is( 'uiElement' ) ).length;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/attributeelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/emptyelement\n */\n\nimport Element from './element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Node from './node';\n\n/**\n * EmptyElement class. It is used to represent elements that cannot contain any child nodes.\n */\nexport default class EmptyElement extends Element {\n\t/**\n\t * Creates new instance of EmptyElement.\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 EmptyElement is incorrect (adding child nodes to EmptyElement is forbidden).\n\t *\n\t * @param {String} name Node name.\n\t * @param {Object|Iterable} [attributes] Collection of attributes.\n\t */\n\tconstructor( name, attributes, children ) {\n\t\tsuper( name, attributes, children );\n\n\t\t/**\n\t\t * Returns `null` because filler is not needed for EmptyElements.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {null} Always returns null.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'emptyElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'emptyElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\t/**\n\t * Overrides {@link module:engine/view/element~Element#insertChildren} method.\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` to prevent\n\t * adding any child nodes to EmptyElement.\n\t */\n\tinsertChildren( index, nodes ) {\n\t\tif ( nodes && ( nodes instanceof Node || Array.from( nodes ).length > 0 ) ) {\n\t\t\t/**\n\t\t\t * Cannot add children to {@link module:engine/view/emptyelement~EmptyElement}.\n\t\t\t *\n\t\t\t * @error view-emptyelement-cannot-add\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-emptyelement-cannot-add: Cannot add child nodes to EmptyElement instance.' );\n\t\t}\n\t}\n}\n\n// Returns `null` because block filler is not needed for EmptyElements.\n//\n// @returns {null}\nfunction getFillerOffset() {\n\treturn null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/emptyelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals navigator:false */\n\n/**\n * @module utils/env\n */\n\nconst userAgent = navigator.userAgent.toLowerCase();\n\n/**\n * A namespace containing environment and browser information.\n *\n * @namespace\n */\nconst env = {\n\t/**\n\t * Indicates that application is running on Macintosh.\n\t *\n\t * @static\n\t * @member {Boolean} module:utils/env~env#mac\n\t */\n\tmac: isMac( userAgent )\n};\n\nexport default env;\n\n/**\n * Checks if User Agent represented by the string is running on Macintosh.\n *\n * @param {String} userAgent **Lowercase** `navigator.userAgent` string.\n * @returns {Boolean} Whether User Agent is running on Macintosh or not.\n */\nexport function isMac( userAgent ) {\n\treturn userAgent.indexOf( 'macintosh' ) > -1;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/env.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * Set of utils related to keyboard support.\n *\n * @module utils/keyboard\n */\n\nimport CKEditorError from './ckeditorerror';\nimport env from './env';\n\n/**\n * Object with `keyName => keyCode` pairs for a set of known keys.\n *\n * Contains:\n *\n * * `a-z`,\n * * `0-9`,\n * * `f1-f12`,\n * * `arrow(left|up|right|bottom)`,\n * * `backspace`, `delete`, `enter`, `esc`, `tab`,\n * * `ctrl`, `cmd`, `shift`, `alt`.\n */\nexport const keyCodes = generateKnownKeyCodes();\n\n/**\n * Converts a key name or a {@link module:utils/keyboard~KeystrokeInfo keystroke info} into a key code.\n *\n * Note: Key names are matched with {@link module:utils/keyboard~keyCodes} in a case-insensitive way.\n *\n * @param {String|module:utils/keyboard~KeystrokeInfo} Key name (see {@link module:utils/keyboard~keyCodes})\n * or a keystroke data object.\n * @returns {Number} Key or keystroke code.\n */\nexport function getCode( key ) {\n\tlet keyCode;\n\n\tif ( typeof key == 'string' ) {\n\t\tkeyCode = keyCodes[ key.toLowerCase() ];\n\n\t\tif ( !keyCode ) {\n\t\t\t/**\n\t\t\t * Unknown key name. Only key names contained by the {@link module:utils/keyboard~keyCodes} can be used.\n\t\t\t *\n\t\t\t * @errror keyboard-unknown-key\n\t\t\t * @param {String} key\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'keyboard-unknown-key: Unknown key name.', { key } );\n\t\t}\n\t} else {\n\t\tkeyCode = key.keyCode +\n\t\t\t( key.altKey ? keyCodes.alt : 0 ) +\n\t\t\t( key.ctrlKey ? keyCodes.ctrl : 0 ) +\n\t\t\t( key.shiftKey ? keyCodes.shift : 0 );\n\t}\n\n\treturn keyCode;\n}\n\n/**\n * Parses keystroke and returns a keystroke code that will match the code returned by\n * link {@link module:utils/keyboard.getCode} for a corresponding {@link module:utils/keyboard~KeystrokeInfo keystroke info}.\n *\n * The keystroke can be passed in two formats:\n *\n * * as a single string e.g. `ctrl + A`,\n * * as an array of {@link module:utils/keyboard~keyCodes known key names} and key codes e.g.:\n * * `[ 'ctrl', 32 ]` (ctrl + space),\n * * `[ 'ctrl', 'a' ]` (ctrl + A).\n *\n * Note: Key names are matched with {@link module:utils/keyboard~keyCodes} in a case-insensitive way.\n *\n * Note: Only keystrokes with a single non-modifier key are supported (e.g. `ctrl+A` is OK, but `ctrl+A+B` is not).\n *\n * @param {String|Array.<Number|String>} keystroke Keystroke definition.\n * @returns {Number} Keystroke code.\n */\nexport function parseKeystroke( keystroke ) {\n\tif ( typeof keystroke == 'string' ) {\n\t\tkeystroke = splitKeystrokeText( keystroke );\n\t}\n\n\treturn keystroke\n\t\t.map( key => ( typeof key == 'string' ) ? getCode( key ) : key )\n\t\t.reduce( ( key, sum ) => sum + key, 0 );\n}\n\n/**\n * It translates any keystroke string text like `\"CTRL+A\"` to an\n * environmentspecific keystroke, i.e. `\"⌘A\"` on Mac OSX.\n *\n * @param {String} keystroke Keystroke text.\n * @returns {String} Keystroke text specific for the environment.\n */\nexport function getEnvKeystrokeText( keystroke ) {\n\tconst split = splitKeystrokeText( keystroke );\n\n\tif ( env.mac ) {\n\t\tif ( split[ 0 ].toLowerCase() == 'ctrl' ) {\n\t\t\treturn '⌘' + ( split[ 1 ] || '' );\n\t\t}\n\t}\n\n\treturn keystroke;\n}\n\nfunction generateKnownKeyCodes() {\n\tconst keyCodes = {\n\t\tarrowleft: 37,\n\t\tarrowup: 38,\n\t\tarrowright: 39,\n\t\tarrowdown: 40,\n\t\tbackspace: 8,\n\t\tdelete: 46,\n\t\tenter: 13,\n\t\tspace: 32,\n\t\tesc: 27,\n\t\ttab: 9,\n\n\t\t// The idea about these numbers is that they do not collide with any real key codes, so we can use them\n\t\t// like bit masks.\n\t\tctrl: 0x110000,\n\t\t// Has the same code as ctrl, because their behaviour should be unified across the editor.\n\t\t// See http://ckeditor.github.io/editor-recommendations/general-policies#ctrl-vs-cmd\n\t\tcmd: 0x110000,\n\t\tshift: 0x220000,\n\t\talt: 0x440000\n\t};\n\n\t// a-z\n\tfor ( let code = 65; code <= 90; code++ ) {\n\t\tconst letter = String.fromCharCode( code );\n\n\t\tkeyCodes[ letter.toLowerCase() ] = code;\n\t}\n\n\t// 0-9\n\tfor ( let code = 48; code <= 57; code++ ) {\n\t\tkeyCodes[ code - 48 ] = code;\n\t}\n\n\t// F1-F12\n\tfor ( let code = 112; code <= 123; code++ ) {\n\t\tkeyCodes[ 'f' + ( code - 111 ) ] = code;\n\t}\n\n\treturn keyCodes;\n}\n\nfunction splitKeystrokeText( keystroke ) {\n\treturn keystroke.split( /\\s*\\+\\s*/ );\n}\n\n/**\n * Information about a keystroke.\n *\n * @interface module:utils/keyboard~KeystrokeInfo\n */\n\n/**\n * The [key code](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode).\n *\n * @member {Number} module:utils/keyboard~KeystrokeInfo#keyCode\n */\n\n/**\n * Whether the <kbd>Alt</kbd> modifier was pressed.\n *\n * @member {Bolean} module:utils/keyboard~KeystrokeInfo#altKey\n */\n\n/**\n * Whether the <kbd>Ctrl</kbd> or <kbd>Cmd</kbd> modifier was pressed.\n *\n * @member {Bolean} module:utils/keyboard~KeystrokeInfo#ctrlKey\n */\n\n/**\n * Whether the <kbd>Shift</kbd> modifier was pressed.\n *\n * @member {Bolean} module:utils/keyboard~KeystrokeInfo#shiftKey\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/keyboard.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/uielement\n */\n\nimport Element from './element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Node from './node';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * UIElement class. It is used to represent UI not a content of the document.\n * This element can't be split and selection can't be placed inside this element.\n */\nexport default class UIElement extends Element {\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 * @param {String} name Node name.\n\t * @param {Object|Iterable} [attributes] Collection of attributes.\n\t */\n\tconstructor( name, attributes, children ) {\n\t\tsuper( name, attributes, children );\n\n\t\t/**\n\t\t * Returns `null` because filler is not needed for UIElements.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {null} Always returns null.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'uiElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'uiElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\t/**\n\t * Overrides {@link module:engine/view/element~Element#insertChildren} 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\tinsertChildren( index, nodes ) {\n\t\tif ( nodes && ( nodes instanceof Node || Array.from( nodes ).length > 0 ) ) {\n\t\t\t/**\n\t\t\t * Cannot add children to {@link module:engine/view/uielement~UIElement}.\n\t\t\t *\n\t\t\t * @error view-uielement-cannot-add\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-uielement-cannot-add: Cannot add child nodes to UIElement instance.' );\n\t\t}\n\t}\n\n\t/**\n\t * Renders this {@link module:engine/view/uielement~UIElement} to DOM. This method is called by\n\t * {@link module:engine/view/domconverter~DomConverter}.\n\t *\n\t * @param {Document} domDocument\n\t * @return {HTMLElement}\n\t */\n\trender( domDocument ) {\n\t\tconst domElement = domDocument.createElement( this.name );\n\n\t\tfor ( const key of this.getAttributeKeys() ) {\n\t\t\tdomElement.setAttribute( key, this.getAttribute( key ) );\n\t\t}\n\n\t\treturn domElement;\n\t}\n}\n\n/**\n * This function injects UI element handling to the given {@link module:engine/view/document~Document document}.\n *\n * A callback is added to {@link module:engine/view/document~Document#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 {module:engine/view/document~Document} document Document to which the quirks handling will be injected.\n */\nexport function injectUiElementHandling( document ) {\n\tdocument.on( 'keydown', ( evt, data ) => jumpOverUiElement( evt, data, document.domConverter ) );\n}\n\n// Returns `null` because block filler is not needed for UIElements.\n//\n// @returns {null}\nfunction getFillerOffset() {\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.\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\n\t\t// Jump over UI element if selection is collapsed or shift key is pressed. These are the cases when selection would extend.\n\t\tif ( domSelectionCollapsed || data.shiftKey ) {\n\t\t\tconst domParent = domSelection.focusNode;\n\t\t\tconst domOffset = domSelection.focusOffset;\n\n\t\t\tconst viewPosition = domConverter.domPositionToView( domParent, domOffset );\n\n\t\t\t// In case if dom element is not converted to view or is not mapped or something. Happens for example in some tests.\n\t\t\tif ( viewPosition === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip all following ui elements.\n\t\t\tlet jumpedOverAnyUiElement = false;\n\n\t\t\tconst nextViewPosition = viewPosition.getLastMatchingPosition( value => {\n\t\t\t\tif ( value.item.is( 'uiElement' ) ) {\n\t\t\t\t\t// Remember that there was at least one ui element.\n\t\t\t\t\tjumpedOverAnyUiElement = true;\n\t\t\t\t}\n\n\t\t\t\t// Jump over ui elements, jump over empty attribute elements, move up from inside of attribute element.\n\t\t\t\tif ( value.item.is( 'uiElement' ) || value.item.is( 'attributeElement' ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// Don't jump over text or don't get out of container element.\n\t\t\t\treturn false;\n\t\t\t} );\n\n\t\t\t// If anything has been skipped, fix position.\n\t\t\t// This `if` could be possibly omitted but maybe it is better not to mess with DOM selection if not needed.\n\t\t\tif ( jumpedOverAnyUiElement ) {\n\t\t\t\tconst newDomPosition = domConverter.viewPositionToDom( nextViewPosition );\n\n\t\t\t\tif ( domSelectionCollapsed ) {\n\t\t\t\t\t// Selection was collapsed, so collapse it at further position.\n\t\t\t\t\tdomSelection.collapse( newDomPosition.parent, newDomPosition.offset );\n\t\t\t\t} else {\n\t\t\t\t\t// Selection was not collapse, so extend it instead of collapsing.\n\t\t\t\t\tdomSelection.extend( newDomPosition.parent, newDomPosition.offset );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/uielement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/documentfragment\n */\n\nimport Text from './text';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\n\n/**\n * DocumentFragment class.\n */\nexport default class DocumentFragment {\n\t/**\n\t * Creates new DocumentFragment instance.\n\t *\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] List of nodes to be inserted into\n\t * created document fragment.\n\t */\n\tconstructor( children ) {\n\t\t/**\n\t\t * Array of child nodes.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/view/element~Element>} module:engine/view/documentfragment~DocumentFragment#_children\n\t\t */\n\t\tthis._children = [];\n\n\t\tif ( children ) {\n\t\t\tthis.insertChildren( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Iterates over nodes added to this DocumentFragment.\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Number of child nodes in this document fragment.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t *\n\t * @readonly\n\t * @type {null}\n\t */\n\tget parent() {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether given view tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/view/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'documentFragment';\n\t}\n\n\t/**\n\t * {@link module:engine/view/documentfragment~DocumentFragment#insertChildren 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 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} nodes Node or the list of nodes to be inserted.\n\t * @returns {Number} Number of appended nodes.\n\t */\n\tappendChildren( nodes ) {\n\t\treturn this.insertChildren( this.childCount, nodes );\n\t}\n\n\t/**\n\t * Gets child at the given index.\n\t *\n\t * @param {Number} index Index of child.\n\t * @returns {module:engine/view/node~Node} Child node.\n\t */\n\tgetChild( index ) {\n\t\treturn this._children[ index ];\n\t}\n\n\t/**\n\t * Gets index of the given child node. Returns `-1` if child node is not found.\n\t *\n\t * @param {module:engine/view/node~Node} node Child node.\n\t * @returns {Number} Index of the child node.\n\t */\n\tgetChildIndex( node ) {\n\t\treturn this._children.indexOf( node );\n\t}\n\n\t/**\n\t * Gets child nodes iterator.\n\t *\n\t * @returns {Iterable.<module:engine/view/node~Node>} Child nodes iterator.\n\t */\n\tgetChildren() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\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 * @param {Number} index Position where nodes should be inserted.\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} nodes Node or list of nodes to be inserted.\n\t * @returns {Number} Number of inserted nodes.\n\t */\n\tinsertChildren( index, nodes ) {\n\t\tthis._fireChange( 'children', this );\n\t\tlet count = 0;\n\n\t\tnodes = normalize( nodes );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode.remove();\n\t\t\t}\n\n\t\t\tnode.parent = this;\n\n\t\t\tthis._children.splice( index, 0, node );\n\t\t\tindex++;\n\t\t\tcount++;\n\t\t}\n\n\t\treturn count;\n\t}\n\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 * @param {Number} index Number of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/view/node~Node>} The array of removed nodes.\n\t */\n\tremoveChildren( index, howMany = 1 ) {\n\t\tthis._fireChange( 'children', this );\n\n\t\tfor ( let i = index; i < index + howMany; i++ ) {\n\t\t\tthis._children[ i ].parent = null;\n\t\t}\n\n\t\treturn this._children.splice( index, howMany );\n\t}\n\n\t/**\n\t * Fires `change` event with given type of the change.\n\t *\n\t * @private\n\t * @param {module:engine/view/document~ChangeType} type Type of the change.\n\t * @param {module:engine/view/node~Node} node Changed node.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\t_fireChange( type, node ) {\n\t\tthis.fire( 'change:' + type, node );\n\t}\n}\n\nmix( DocumentFragment, EmitterMixin );\n\n// Converts strings to Text and non-iterables to arrays.\n//\n// @param {String|module:engine/view/node~Node|Iterable.<String|module:engine/view/node~Node>}\n// @return {Iterable.<module:engine/view/node~Node>}\nfunction normalize( nodes ) {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\treturn typeof node == 'string' ? new Text( node ) : node;\n\t\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/documentfragment.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module module:engine/view/writer\n */\n\nimport Position from './position';\nimport ContainerElement from './containerelement';\nimport AttributeElement from './attributeelement';\nimport EmptyElement from './emptyelement';\nimport UIElement from './uielement';\nimport Text from './text';\nimport Range from './range';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport DocumentFragment from './documentfragment';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * Contains functions used for composing view tree.\n *\n * @namespace writer\n */\n\nconst writer = {\n\tbreakAttributes,\n\tbreakContainer,\n\tmergeAttributes,\n\tmergeContainers,\n\tinsert,\n\tremove,\n\tclear,\n\tmove,\n\twrap,\n\twrapPosition,\n\tunwrap,\n\trename\n};\n\nexport default writer;\n\n/**\n * Breaks attribute nodes at provided position or at boundaries of provided range. It breaks attribute elements inside\n * up to a container element.\n *\n * In following examples `<p>` is a container, `<b>` and `<u>` are attribute nodes:\n *\n *\t\t<p>foo<b><u>bar{}</u></b></p> -> <p>foo<b><u>bar</u></b>[]</p>\n *\t\t<p>foo<b><u>{}bar</u></b></p> -> <p>foo{}<b><u>bar</u></b></p>\n *\t\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\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 *\n * **Note:** {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.\n *\n * **Note:** Difference between {@link module:engine/view/writer~writer.breakAttributes breakAttributes} and\n * {@link module:engine/view/writer~writer.breakContainer breakContainer} is that `breakAttributes` breaks all\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of given `position`, up to the first\n * encountered {@link module:engine/view/containerelement~ContainerElement container element}. `breakContainer` assumes that given\n * `position`\n * is directly in container element and breaks that container element.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container`\n * when {@link module:engine/view/range~Range#start start}\n * and {@link module:engine/view/range~Range#end end} positions of a passed range are not placed inside same parent container.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-empty-element`\n * when trying to break attributes\n * inside {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-ui-element`\n * when trying to break attributes\n * inside {@link module:engine/view/uielement~UIElement UIElement}.\n *\n * @see module:engine/view/attributeelement~AttributeElement\n * @see module:engine/view/containerelement~ContainerElement\n * @see module:engine/view/writer~writer.breakContainer\n * @function module:engine/view/writer~writer.breakAttributes\n * @param {module:engine/view/position~Position|module:engine/view/range~Range} positionOrRange Position where to break attribute elements.\n * @returns {module:engine/view/position~Position|module:engine/view/range~Range} New position or range, after breaking the attribute\n * elements.\n */\nexport function breakAttributes( positionOrRange ) {\n\tif ( positionOrRange instanceof Position ) {\n\t\treturn _breakAttributes( positionOrRange );\n\t} else {\n\t\treturn _breakAttributesRange( positionOrRange );\n\t}\n}\n\n/**\n * Breaks {@link module:engine/view/containerelement~ContainerElement container view element} into two, at the given position. Position\n * has to be directly inside container element and cannot be in root. Does not break if position is at the beginning\n * or at the end of it's parent element.\n *\n *\t\t<p>foo^bar</p> -> <p>foo</p><p>bar</p>\n *\t\t<div><p>foo</p>^<p>bar</p></div> -> <div><p>foo</p></div><div><p>bar</p></div>\n *\t\t<p>^foobar</p> -> ^<p>foobar</p>\n *\t\t<p>foobar^</p> -> <p>foobar</p>^\n *\n * **Note:** Difference between {@link module:engine/view/writer~writer.breakAttributes breakAttributes} and\n * {@link module:engine/view/writer~writer.breakContainer breakContainer} is that `breakAttributes` breaks all\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of given `position`, up to the first\n * encountered {@link module:engine/view/containerelement~ContainerElement container element}. `breakContainer` assumes that given\n * `position`\n * is directly in container element and breaks that container element.\n *\n * @see module:engine/view/attributeelement~AttributeElement\n * @see module:engine/view/containerelement~ContainerElement\n * @see module:engine/view/writer~writer.breakAttributes\n * @function module:engine/view/writer~writer.breakContainer\n * @param {module:engine/view/position~Position} position Position where to break element.\n * @returns {module:engine/view/position~Position} Position between broken elements. If element has not been broken, the returned position\n * is placed either before it or after it.\n */\nexport function breakContainer( position ) {\n\tconst element = position.parent;\n\n\tif ( !( element.is( 'containerElement' ) ) ) {\n\t\t/**\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: Trying to break an element which is not a container element.' );\n\t}\n\n\tif ( !element.parent ) {\n\t\t/**\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: Trying to break root element.' );\n\t}\n\n\tif ( position.isAtStart ) {\n\t\treturn Position.createBefore( element );\n\t} else if ( !position.isAtEnd ) {\n\t\tconst newElement = element.clone( false );\n\n\t\tinsert( Position.createAfter( element ), newElement );\n\n\t\tconst sourceRange = new Range( position, Position.createAt( element, 'end' ) );\n\t\tconst targetPosition = new Position( newElement, 0 );\n\n\t\tmove( sourceRange, targetPosition );\n\t}\n\n\treturn Position.createAfter( element );\n}\n\n/**\n * Merges {@link module:engine/view/attributeelement~AttributeElement attribute elements}. It also merges text nodes if needed.\n * Only {@link module:engine/view/attributeelement~AttributeElement#isSimilar similar} attribute elements can be merged.\n *\n * In following examples `<p>` is a container and `<b>` is an attribute element:\n *\n *\t\t<p>foo[]bar</p> -> <p>foo{}bar</p>\n *\t\t<p><b>foo</b>[]<b>bar</b></p> -> <p><b>foo{}bar</b></p>\n *\t\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 *\n * It will also take care about empty attributes when merging:\n *\n *\t\t<p><b>[]</b></p> -> <p>[]</p>\n *\t\t<p><b>foo</b><i>[]</i><b>bar</b></p> -> <p><b>foo{}bar</b></p>\n *\n * **Note:** Difference between {@link module:engine/view/writer~writer.mergeAttributes mergeAttributes} and\n * {@link module:engine/view/writer~writer.mergeContainers mergeContainers} is that `mergeAttributes` merges two\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} or {@link module:engine/view/text~Text text nodes}\n * while `mergeContainer` merges two {@link module:engine/view/containerelement~ContainerElement container elements}.\n *\n * @see module:engine/view/attributeelement~AttributeElement\n * @see module:engine/view/containerelement~ContainerElement\n * @see module:engine/view/writer~writer.mergeContainers\n * @function module:engine/view/writer~writer.mergeAttributes\n * @param {module:engine/view/position~Position} position Merge position.\n * @returns {module:engine/view/position~Position} Position after merge.\n */\nexport function mergeAttributes( position ) {\n\tconst positionOffset = position.offset;\n\tconst positionParent = position.parent;\n\n\t// When inside text node - nothing to merge.\n\tif ( positionParent.is( 'text' ) ) {\n\t\treturn position;\n\t}\n\n\t// When inside empty attribute - remove it.\n\tif ( positionParent.is( 'attributeElement' ) && positionParent.childCount === 0 ) {\n\t\tconst parent = positionParent.parent;\n\t\tconst offset = positionParent.index;\n\t\tpositionParent.remove();\n\n\t\treturn mergeAttributes( new Position( parent, offset ) );\n\t}\n\n\tconst nodeBefore = positionParent.getChild( positionOffset - 1 );\n\tconst nodeAfter = positionParent.getChild( positionOffset );\n\n\t// Position should be placed between two nodes.\n\tif ( !nodeBefore || !nodeAfter ) {\n\t\treturn position;\n\t}\n\n\t// When position is between two text nodes.\n\tif ( nodeBefore.is( 'text' ) && nodeAfter.is( 'text' ) ) {\n\t\treturn mergeTextNodes( nodeBefore, nodeAfter );\n\t}\n\t// When selection is between two same attribute elements.\n\telse if ( nodeBefore.is( 'attributeElement' ) && nodeAfter.is( 'attributeElement' ) && nodeBefore.isSimilar( nodeAfter ) ) {\n\t\t// Move all children nodes from node placed after selection and remove that node.\n\t\tconst count = nodeBefore.childCount;\n\t\tnodeBefore.appendChildren( nodeAfter.getChildren() );\n\t\tnodeAfter.remove();\n\n\t\t// New position is located inside the first node, before new nodes.\n\t\t// Call this method recursively to merge again if needed.\n\t\treturn mergeAttributes( new Position( nodeBefore, count ) );\n\t}\n\n\treturn position;\n}\n\n/**\n * Merges two {@link module:engine/view/containerelement~ContainerElement container elements} that are before and after given position.\n * Precisely, the element after the position is removed and it's contents are moved to element before the position.\n *\n *\t\t<p>foo</p>^<p>bar</p> -> <p>foo^bar</p>\n *\t\t<div>foo</div>^<p>bar</p> -> <div>foo^bar</div>\n *\n * **Note:** Difference between {@link module:engine/view/writer~writer.mergeAttributes mergeAttributes} and\n * {@link module:engine/view/writer~writer.mergeContainers mergeContainers} is that `mergeAttributes` merges two\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} or {@link module:engine/view/text~Text text nodes}\n * while `mergeContainer` merges two {@link module:engine/view/containerelement~ContainerElement container elements}.\n *\n * @see module:engine/view/attributeelement~AttributeElement\n * @see module:engine/view/containerelement~ContainerElement\n * @see module:engine/view/writer~writer.mergeAttributes\n * @function module:engine/view/writer~writer.mergeContainers\n * @param {module:engine/view/position~Position} position Merge position.\n * @returns {module:engine/view/position~Position} Position after merge.\n */\nexport function mergeContainers( position ) {\n\tconst prev = position.nodeBefore;\n\tconst next = position.nodeAfter;\n\n\tif ( !prev || !next || !prev.is( 'containerElement' ) || !next.is( 'containerElement' ) ) {\n\t\t/**\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: ' +\n\t\t\t'Element before and after given position cannot be merged.' );\n\t}\n\n\tconst lastChild = prev.getChild( prev.childCount - 1 );\n\tconst newPosition = lastChild instanceof Text ? Position.createAt( lastChild, 'end' ) : Position.createAt( prev, 'end' );\n\n\tmove( Range.createIn( next ), Position.createAt( prev, 'end' ) );\n\tremove( Range.createOn( next ) );\n\n\treturn newPosition;\n}\n\n/**\n * Insert node or nodes at specified position. Takes care about breaking attributes before insertion\n * and merging them afterwards.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n * contains instances that are not {@link module:engine/view/text~Text Texts},\n * {@link module:engine/view/attributeelement~AttributeElement AttributeElements},\n * {@link module:engine/view/containerelement~ContainerElement ContainerElements},\n * {@link module:engine/view/emptyelement~EmptyElement EmptyElements} or\n * {@link module:engine/view/uielement~UIElement UIElements}.\n *\n * @function insert\n * @param {module:engine/view/position~Position} position Insertion position.\n * @param {module:engine/view/text~Text|module:engine/view/attributeelement~AttributeElement|\n * module:engine/view/containerelement~ContainerElement|module:engine/view/emptyelement~EmptyElement|\n * module:engine/view/uielement~UIElement|Iterable.<module:engine/view/text~Text|\n * module:engine/view/attributeelement~AttributeElement|module:engine/view/containerelement~ContainerElement|\n * module:engine/view/emptyelement~EmptyElement|module:engine/view/uielement~UIElement>} nodes Node or nodes to insert.\n * @returns {module:engine/view/range~Range} Range around inserted nodes.\n */\nexport function insert( position, nodes ) {\n\tnodes = isIterable( nodes ) ? [ ...nodes ] : [ nodes ];\n\n\t// Check if nodes to insert are instances of AttributeElements, ContainerElements, EmptyElements, UIElements or Text.\n\tvalidateNodesToInsert( nodes );\n\n\tconst container = getParentContainer( position );\n\n\tif ( !container ) {\n\t\t/**\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' );\n\t}\n\n\tconst insertionPosition = _breakAttributes( position, true );\n\n\tconst length = container.insertChildren( insertionPosition.offset, nodes );\n\tconst endPosition = insertionPosition.getShiftedBy( length );\n\tconst start = mergeAttributes( insertionPosition );\n\n\t// When no nodes were inserted - return collapsed range.\n\tif ( length === 0 ) {\n\t\treturn new Range( start, start );\n\t} else {\n\t\t// If start position was merged - move end position.\n\t\tif ( !start.isEqual( insertionPosition ) ) {\n\t\t\tendPosition.offset--;\n\t\t}\n\n\t\tconst end = mergeAttributes( endPosition );\n\n\t\treturn new Range( start, end );\n\t}\n}\n\n/**\n * Removes provided range from the container.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n * same parent container.\n *\n * @function module:engine/view/writer~writer.remove\n * @param {module:engine/view/range~Range} range Range to remove from container. After removing, it will be updated\n * to a collapsed range showing the new position.\n * @returns {module:engine/view/documentfragment~DocumentFragment} Document fragment containing removed nodes.\n */\nexport function remove( range ) {\n\tvalidateRangeContainer( range );\n\n\t// If range is collapsed - nothing to remove.\n\tif ( range.isCollapsed ) {\n\t\treturn new DocumentFragment();\n\t}\n\n\t// Break attributes at range start and end.\n\tconst { start: breakStart, end: breakEnd } = _breakAttributesRange( range, true );\n\tconst parentContainer = breakStart.parent;\n\n\tconst count = breakEnd.offset - breakStart.offset;\n\n\t// Remove nodes in range.\n\tconst removed = parentContainer.removeChildren( breakStart.offset, count );\n\n\t// Merge after removing.\n\tconst mergePosition = mergeAttributes( breakStart );\n\trange.start = mergePosition;\n\trange.end = Position.createFromPosition( mergePosition );\n\n\t// Return removed nodes.\n\treturn new DocumentFragment( removed );\n}\n\n/**\n * Removes matching elements from given range.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n * same parent container.\n *\n * @function module:engine/view/writer~writer.clear\n * @param {module:engine/view/range~Range} range Range to clear.\n * @param {module:engine/view/element~Element} element Element to remove.\n */\nexport function clear( range, element ) {\n\tvalidateRangeContainer( range );\n\n\t// Create walker on given range.\n\t// We walk backward because when we remove element during walk it modifies range end position.\n\tconst walker = range.getWalker( {\n\t\tdirection: 'backward',\n\t\tignoreElementEnd: true\n\t} );\n\n\t// Let's walk.\n\tfor ( const current of walker ) {\n\t\tconst item = current.item;\n\t\tlet rangeToRemove;\n\n\t\t// When current item matches to the given element.\n\t\tif ( item.is( 'element' ) && element.isSimilar( item ) ) {\n\t\t\t// Create range on this element.\n\t\t\trangeToRemove = Range.createOn( item );\n\t\t// When range starts inside Text or TextProxy element.\n\t\t} else if ( !current.nextPosition.isAfter( range.start ) && ( item.is( 'text' ) || item.is( 'textProxy' ) ) ) {\n\t\t\t// We need to check if parent of this text matches to given element.\n\t\t\tconst parentElement = item.getAncestors().find( ancestor => {\n\t\t\t\treturn ancestor.is( 'element' ) && element.isSimilar( ancestor );\n\t\t\t} );\n\n\t\t\t// If it is then create range inside this element.\n\t\t\tif ( parentElement ) {\n\t\t\t\trangeToRemove = Range.createIn( parentElement );\n\t\t\t}\n\t\t}\n\n\t\t// If we have found element to remove.\n\t\tif ( rangeToRemove ) {\n\t\t\t// We need to check if element range stick out of the given range and truncate if it is.\n\t\t\tif ( rangeToRemove.end.isAfter( range.end ) ) {\n\t\t\t\trangeToRemove.end = range.end;\n\t\t\t}\n\n\t\t\tif ( rangeToRemove.start.isBefore( range.start ) ) {\n\t\t\t\trangeToRemove.start = range.start;\n\t\t\t}\n\n\t\t\t// At the end we remove range with found element.\n\t\t\tremove( rangeToRemove );\n\t\t}\n\t}\n}\n\n/**\n * Moves nodes from provided range to target position.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n * same parent container.\n *\n * @function module:engine/view/writer~writer.move\n * @param {module:engine/view/range~Range} sourceRange Range containing nodes to move.\n * @param {module:engine/view/position~Position} targetPosition Position to insert.\n * @returns {module:engine/view/range~Range} Range in target container. Inserted nodes are placed between\n * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions.\n */\nexport function move( sourceRange, targetPosition ) {\n\tlet nodes;\n\n\tif ( targetPosition.isAfter( sourceRange.end ) ) {\n\t\ttargetPosition = _breakAttributes( targetPosition, true );\n\n\t\tconst parent = targetPosition.parent;\n\t\tconst countBefore = parent.childCount;\n\n\t\tsourceRange = _breakAttributesRange( sourceRange, true );\n\n\t\tnodes = remove( sourceRange );\n\n\t\ttargetPosition.offset += ( parent.childCount - countBefore );\n\t} else {\n\t\tnodes = remove( sourceRange );\n\t}\n\n\treturn insert( targetPosition, nodes );\n}\n\n/**\n * Wraps elements within range with provided {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-invalid-range-container`\n * when {@link module:engine/view/range~Range#start}\n * and {@link module:engine/view/range~Range#end} positions are not placed inside same parent container.\n * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n * an instance of {module:engine/view/attributeelement~AttributeElement AttributeElement}.\n *\n * @function module:engine/view/writer~writer.wrap\n * @param {module:engine/view/range~Range} range Range to wrap.\n * @param {module:engine/view/attributeelement~AttributeElement} attribute Attribute element to use as wrapper.\n */\nexport function wrap( range, attribute ) {\n\tif ( !( attribute instanceof AttributeElement ) ) {\n\t\tthrow new CKEditorError( 'view-writer-wrap-invalid-attribute' );\n\t}\n\n\tvalidateRangeContainer( range );\n\n\t// If range is collapsed - nothing to wrap.\n\tif ( range.isCollapsed ) {\n\t\treturn range;\n\t}\n\n\t// Range around one element.\n\tif ( range.end.isEqual( range.start.getShiftedBy( 1 ) ) ) {\n\t\tconst node = range.start.nodeAfter;\n\n\t\tif ( node instanceof AttributeElement && wrapAttributeElement( attribute, node ) ) {\n\t\t\treturn range;\n\t\t}\n\t}\n\n\t// Range is inside single attribute and spans on all children.\n\tif ( rangeSpansOnAllChildren( range ) && wrapAttributeElement( attribute, range.start.parent ) ) {\n\t\tconst parent = range.start.parent.parent;\n\t\tconst index = range.start.parent.index;\n\n\t\treturn Range.createFromParentsAndOffsets( parent, index, parent, index + 1 );\n\t}\n\n\t// Break attributes at range start and end.\n\tconst { start: breakStart, end: breakEnd } = _breakAttributesRange( range, true );\n\tconst parentContainer = breakStart.parent;\n\n\t// Unwrap children located between break points.\n\tconst unwrappedRange = unwrapChildren( parentContainer, breakStart.offset, breakEnd.offset, attribute );\n\n\t// Wrap all children with attribute.\n\tconst newRange = wrapChildren( parentContainer, unwrappedRange.start.offset, unwrappedRange.end.offset, attribute );\n\n\t// Merge attributes at the both ends and return a new range.\n\tconst start = mergeAttributes( newRange.start );\n\n\t// If start position was merged - move end position back.\n\tif ( !start.isEqual( newRange.start ) ) {\n\t\tnewRange.end.offset--;\n\t}\n\tconst end = mergeAttributes( newRange.end );\n\n\treturn new Range( start, end );\n}\n\n/**\n * Wraps position with provided attribute. Returns new position after wrapping. This method will also merge newly\n * added attribute with its siblings whenever possible.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n * an instance of {module:engine/view/attributeelement~AttributeElement AttributeElement}.\n *\n * @param {module:engine/view/position~Position} position\n * @param {module:engine/view/attributeelement~AttributeElement} attribute\n * @returns {module:engine/view/position~Position} New position after wrapping.\n */\nexport function wrapPosition( position, attribute ) {\n\tif ( !( attribute instanceof AttributeElement ) ) {\n\t\tthrow new CKEditorError( 'view-writer-wrap-invalid-attribute' );\n\t}\n\n\t// Return same position when trying to wrap with attribute similar to position parent.\n\tif ( attribute.isSimilar( position.parent ) ) {\n\t\treturn movePositionToTextNode( Position.createFromPosition( position ) );\n\t}\n\n\t// When position is inside text node - break it and place new position between two text nodes.\n\tif ( position.parent.is( 'text' ) ) {\n\t\tposition = breakTextNode( position );\n\t}\n\n\t// Create fake element that will represent position, and will not be merged with other attributes.\n\tconst fakePosition = new AttributeElement();\n\tfakePosition.priority = Number.POSITIVE_INFINITY;\n\tfakePosition.isSimilar = () => false;\n\n\t// Insert fake element in position location.\n\tposition.parent.insertChildren( position.offset, fakePosition );\n\n\t// Range around inserted fake attribute element.\n\tconst wrapRange = new Range( position, position.getShiftedBy( 1 ) );\n\n\t// Wrap fake element with attribute (it will also merge if possible).\n\twrap( wrapRange, attribute );\n\n\t// Remove fake element and place new position there.\n\tconst newPosition = new Position( fakePosition.parent, fakePosition.index );\n\tfakePosition.remove();\n\n\t// If position is placed between text nodes - merge them and return position inside.\n\tconst nodeBefore = newPosition.nodeBefore;\n\tconst nodeAfter = newPosition.nodeAfter;\n\n\tif ( nodeBefore instanceof Text && nodeAfter instanceof Text ) {\n\t\treturn mergeTextNodes( nodeBefore, nodeAfter );\n\t}\n\n\t// If position is next to text node - move position inside.\n\treturn movePositionToTextNode( newPosition );\n}\n\n/**\n * Unwraps nodes within provided range from attribute element.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n * same parent container.\n *\n * @param {module:engine/view/range~Range} range\n * @param {module:engine/view/attributeelement~AttributeElement} element\n */\nexport function unwrap( range, attribute ) {\n\tif ( !( attribute instanceof AttributeElement ) ) {\n\t\t/**\n\t\t * Attribute element need to be instance of attribute element.\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' );\n\t}\n\n\tvalidateRangeContainer( range );\n\n\t// If range is collapsed - nothing to unwrap.\n\tif ( range.isCollapsed ) {\n\t\treturn range;\n\t}\n\n\t// Range around one element - check if AttributeElement can be unwrapped partially when it's not similar.\n\t// For example:\n\t// <b class=\"foo bar\" title=\"baz\"></b> unwrap with:\t<b class=\"foo\"></p> result: <b class\"bar\" title=\"baz\"></b>\n\tif ( range.end.isEqual( range.start.getShiftedBy( 1 ) ) ) {\n\t\tconst node = range.start.nodeAfter;\n\n\t\t// Unwrap single attribute element.\n\t\tif ( !attribute.isSimilar( node ) && node instanceof AttributeElement && unwrapAttributeElement( attribute, node ) ) {\n\t\t\treturn range;\n\t\t}\n\t}\n\n\t// Break attributes at range start and end.\n\tconst { start: breakStart, end: breakEnd } = _breakAttributesRange( range, true );\n\tconst parentContainer = breakStart.parent;\n\n\t// Unwrap children located between break points.\n\tconst newRange = unwrapChildren( parentContainer, breakStart.offset, breakEnd.offset, attribute );\n\n\t// Merge attributes at the both ends and return a new range.\n\tconst start = mergeAttributes( newRange.start );\n\n\t// If start position was merged - move end position back.\n\tif ( !start.isEqual( newRange.start ) ) {\n\t\tnewRange.end.offset--;\n\t}\n\tconst end = mergeAttributes( newRange.end );\n\n\treturn new Range( start, end );\n}\n\n/**\n * Renames element by creating a copy of renamed element but with changed name and then moving contents of the\n * old element to the new one. Keep in mind that this will invalidate all {@link module:engine/view/position~Position positions} which\n * has renamed element as {@link module:engine/view/position~Position#parent a parent}.\n *\n * New element has to be created because `Element#tagName` property in DOM is readonly.\n *\n * Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n *\n * @param {module:engine/view/containerelement~ContainerElement} viewElement Element to be renamed.\n * @param {String} newName New name for element.\n */\nexport function rename( viewElement, newName ) {\n\tconst newElement = new ContainerElement( newName, viewElement.getAttributes() );\n\n\tinsert( Position.createAfter( viewElement ), newElement );\n\tmove( Range.createIn( viewElement ), Position.createAt( newElement ) );\n\tremove( Range.createOn( viewElement ) );\n\n\treturn newElement;\n}\n\n/**\n * Attribute element need to be instance of attribute element.\n *\n * @error view-writer-wrap-invalid-attribute\n */\n\n// Returns first parent container of specified {@link module:engine/view/position~Position Position}.\n// Position's parent node is checked as first, then next parents are checked.\n// Note that {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.\n//\n// @param {module:engine/view/position~Position} position Position used as a start point to locate parent container.\n// @returns {module:engine/view/containerelement~ContainerElement|module:engine/view/documentfragment~DocumentFragment|undefined}\n// Parent container element or `undefined` if container is not found.\nfunction getParentContainer( position ) {\n\tlet parent = position.parent;\n\n\twhile ( !isContainerOrFragment( parent ) ) {\n\t\tif ( !parent ) {\n\t\t\treturn undefined;\n\t\t}\n\t\tparent = parent.parent;\n\t}\n\n\treturn parent;\n}\n\n// Function used by both public breakAttributes (without splitting text nodes) and by other methods (with\n// splitting text nodes).\n//\n// @param {module:engine/view/range~Range} range Range which `start` and `end` positions will be used to break attributes.\n// @param {Boolean} [forceSplitText = false] If set to `true`, will break text nodes even if they are directly in\n// container element. This behavior will result in incorrect view state, but is needed by other view writing methods\n// which then fixes view state. Defaults to `false`.\n// @returns {module:engine/view/range~Range} New range with located at break positions.\nfunction _breakAttributesRange( range, forceSplitText = false ) {\n\tconst rangeStart = range.start;\n\tconst rangeEnd = range.end;\n\n\tvalidateRangeContainer( range );\n\n\t// Break at the collapsed position. Return new collapsed range.\n\tif ( range.isCollapsed ) {\n\t\tconst position = _breakAttributes( range.start, forceSplitText );\n\n\t\treturn new Range( position, position );\n\t}\n\n\tconst breakEnd = _breakAttributes( rangeEnd, forceSplitText );\n\tconst count = breakEnd.parent.childCount;\n\tconst breakStart = _breakAttributes( rangeStart, forceSplitText );\n\n\t// Calculate new break end offset.\n\tbreakEnd.offset += breakEnd.parent.childCount - count;\n\n\treturn new Range( breakStart, breakEnd );\n}\n\n// Function used by public breakAttributes (without splitting text nodes) and by other methods (with\n// splitting text nodes).\n//\n// Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-empty-element` when break position\n// is placed inside {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.\n//\n// Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-ui-element` when break position\n// is placed inside {@link module:engine/view/uielement~UIElement UIElement}.\n//\n// @param {module:engine/view/position~Position} position Position where to break attributes.\n// @param {Boolean} [forceSplitText = false] If set to `true`, will break text nodes even if they are directly in\n// container element. This behavior will result in incorrect view state, but is needed by other view writing methods\n// which then fixes view state. Defaults to `false`.\n// @returns {module:engine/view/position~Position} New position after breaking the attributes.\nfunction _breakAttributes( position, forceSplitText = false ) {\n\tconst positionOffset = position.offset;\n\tconst positionParent = position.parent;\n\n\t// If position is placed inside EmptyElement - throw an exception as we cannot break inside.\n\tif ( position.parent.is( 'emptyElement' ) ) {\n\t\t/**\n\t\t * Cannot break inside EmptyElement instance.\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' );\n\t}\n\n\t// If position is placed inside UIElement - throw an exception as we cannot break inside.\n\tif ( position.parent.is( 'uiElement' ) ) {\n\t\t/**\n\t\t * Cannot break inside UIElement instance.\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' );\n\t}\n\n\t// There are no attributes to break and text nodes breaking is not forced.\n\tif ( !forceSplitText && positionParent.is( 'text' ) && isContainerOrFragment( positionParent.parent ) ) {\n\t\treturn Position.createFromPosition( position );\n\t}\n\n\t// Position's parent is container, so no attributes to break.\n\tif ( isContainerOrFragment( positionParent ) ) {\n\t\treturn Position.createFromPosition( position );\n\t}\n\n\t// Break text and start again in new position.\n\tif ( positionParent.is( 'text' ) ) {\n\t\treturn _breakAttributes( breakTextNode( position ), forceSplitText );\n\t}\n\n\tconst length = positionParent.childCount;\n\n\t// <p>foo<b><u>bar{}</u></b></p>\n\t// <p>foo<b><u>bar</u>[]</b></p>\n\t// <p>foo<b><u>bar</u></b>[]</p>\n\tif ( positionOffset == length ) {\n\t\tconst newPosition = new Position( positionParent.parent, positionParent.index + 1 );\n\n\t\treturn _breakAttributes( newPosition, forceSplitText );\n\t} else\n\t// <p>foo<b><u>{}bar</u></b></p>\n\t// <p>foo<b>[]<u>bar</u></b></p>\n\t// <p>foo{}<b><u>bar</u></b></p>\n\tif ( positionOffset === 0 ) {\n\t\tconst newPosition = new Position( positionParent.parent, positionParent.index );\n\n\t\treturn _breakAttributes( newPosition, forceSplitText );\n\t}\n\t// <p>foo<b><u>b{}ar</u></b></p>\n\t// <p>foo<b><u>b[]ar</u></b></p>\n\t// <p>foo<b><u>b</u>[]<u>ar</u></b></p>\n\t// <p>foo<b><u>b</u></b>[]<b><u>ar</u></b></p>\n\telse {\n\t\tconst offsetAfter = positionParent.index + 1;\n\n\t\t// Break element.\n\t\tconst clonedNode = positionParent.clone();\n\n\t\t// Insert cloned node to position's parent node.\n\t\tpositionParent.parent.insertChildren( offsetAfter, clonedNode );\n\n\t\t// Get nodes to move.\n\t\tconst count = positionParent.childCount - positionOffset;\n\t\tconst nodesToMove = positionParent.removeChildren( positionOffset, count );\n\n\t\t// Move nodes to cloned node.\n\t\tclonedNode.appendChildren( nodesToMove );\n\n\t\t// Create new position to work on.\n\t\tconst newPosition = new Position( positionParent.parent, offsetAfter );\n\n\t\treturn _breakAttributes( newPosition, forceSplitText );\n\t}\n}\n\n// Unwraps children from provided `attribute`. Only children contained in `parent` element between\n// `startOffset` and `endOffset` will be unwrapped.\n//\n// @param {module:engine/view/element~Element} parent\n// @param {Number} startOffset\n// @param {Number} endOffset\n// @param {module:engine/view/element~Element} attribute\nfunction unwrapChildren( parent, startOffset, endOffset, attribute ) {\n\tlet i = startOffset;\n\tconst unwrapPositions = [];\n\n\t// Iterate over each element between provided offsets inside parent.\n\twhile ( i < endOffset ) {\n\t\tconst child = parent.getChild( i );\n\n\t\t// If attributes are the similar, then unwrap.\n\t\tif ( child.isSimilar( attribute ) ) {\n\t\t\tconst unwrapped = child.getChildren();\n\t\t\tconst count = child.childCount;\n\n\t\t\t// Replace wrapper element with its children\n\t\t\tchild.remove();\n\t\t\tparent.insertChildren( i, unwrapped );\n\n\t\t\t// Save start and end position of moved items.\n\t\t\tunwrapPositions.push(\n\t\t\t\tnew Position( parent, i ),\n\t\t\t\tnew Position( parent, i + count )\n\t\t\t);\n\n\t\t\t// Skip elements that were unwrapped. Assuming that there won't be another element to unwrap in child\n\t\t\t// elements.\n\t\t\ti += count;\n\t\t\tendOffset += count - 1;\n\t\t} else {\n\t\t\t// If other nested attribute is found start unwrapping there.\n\t\t\tif ( child.is( 'attributeElement' ) ) {\n\t\t\t\tunwrapChildren( child, 0, child.childCount, attribute );\n\t\t\t}\n\n\t\t\ti++;\n\t\t}\n\t}\n\n\t// Merge at each unwrap.\n\tlet offsetChange = 0;\n\n\tfor ( const position of unwrapPositions ) {\n\t\tposition.offset -= offsetChange;\n\n\t\t// Do not merge with elements outside selected children.\n\t\tif ( position.offset == startOffset || position.offset == endOffset ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst newPosition = mergeAttributes( position );\n\n\t\t// If nodes were merged - other merge offsets will change.\n\t\tif ( !newPosition.isEqual( position ) ) {\n\t\t\toffsetChange++;\n\t\t\tendOffset--;\n\t\t}\n\t}\n\n\treturn Range.createFromParentsAndOffsets( parent, startOffset, parent, endOffset );\n}\n\n// Wraps children with provided `attribute`. Only children contained in `parent` element between\n// `startOffset` and `endOffset` will be wrapped.\n//\n// @param {module:engine/view/element~Element} parent\n// @param {Number} startOffset\n// @param {Number} endOffset\n// @param {module:engine/view/element~Element} attribute\nfunction wrapChildren( parent, startOffset, endOffset, attribute ) {\n\tlet i = startOffset;\n\tconst wrapPositions = [];\n\n\twhile ( i < endOffset ) {\n\t\tconst child = parent.getChild( i );\n\t\tconst isText = child.is( 'text' );\n\t\tconst isAttribute = child.is( 'attributeElement' );\n\t\tconst isEmpty = child.is( 'emptyElement' );\n\t\tconst isUI = child.is( 'uiElement' );\n\n\t\t// Wrap text, empty elements, ui elements or attributes with higher or equal priority.\n\t\tif ( isText || isEmpty || isUI || ( isAttribute && shouldABeOutsideB( attribute, child ) ) ) {\n\t\t\t// Clone attribute.\n\t\t\tconst newAttribute = attribute.clone();\n\n\t\t\t// Wrap current node with new attribute;\n\t\t\tchild.remove();\n\t\t\tnewAttribute.appendChildren( child );\n\t\t\tparent.insertChildren( i, newAttribute );\n\n\t\t\twrapPositions.push(\tnew Position( parent, i ) );\n\t\t}\n\t\t// If other nested attribute is found start wrapping there.\n\t\telse if ( isAttribute ) {\n\t\t\twrapChildren( child, 0, child.childCount, attribute );\n\t\t}\n\n\t\ti++;\n\t}\n\n\t// Merge at each wrap.\n\tlet offsetChange = 0;\n\n\tfor ( const position of wrapPositions ) {\n\t\tposition.offset -= offsetChange;\n\n\t\t// Do not merge with elements outside selected children.\n\t\tif ( position.offset == startOffset ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst newPosition = mergeAttributes( position );\n\n\t\t// If nodes were merged - other merge offsets will change.\n\t\tif ( !newPosition.isEqual( position ) ) {\n\t\t\toffsetChange++;\n\t\t\tendOffset--;\n\t\t}\n\t}\n\n\treturn Range.createFromParentsAndOffsets( parent, startOffset, parent, endOffset );\n}\n\n// Checks if first {@link module:engine/view/attributeelement~AttributeElement AttributeElement} provided to the function\n// can be wrapped otuside second element. It is done by comparing elements'\n// {@link module:engine/view/attributeelement~AttributeElement#priority priorities}, if both have same priority\n// {@link module:engine/view/element~Element#getIdentity identities} are compared.\n//\n// @param {module:engine/view/attributeelement~AttributeElement} a\n// @param {module:engine/view/attributeelement~AttributeElement} b\n// @returns {Boolean}\nfunction shouldABeOutsideB( a, b ) {\n\tif ( a.priority < b.priority ) {\n\t\treturn true;\n\t} else if ( a.priority > b.priority ) {\n\t\treturn false;\n\t}\n\n\t// When priorities are equal and names are different - use identities.\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//\t\t<p>foo[]</p> -> <p>foo{}</p>\n//\t\t<p>[]foo</p> -> <p>{}foo</p>\n//\n// @param {module:engine/view/position~Position} position\n// @returns {module:engine/view/position~Position} Position located inside text node or same position if there is no text nodes\n// before or after position location.\nfunction movePositionToTextNode( position ) {\n\tconst nodeBefore = position.nodeBefore;\n\n\tif ( nodeBefore && nodeBefore.is( 'text' ) ) {\n\t\treturn new Position( nodeBefore, nodeBefore.data.length );\n\t}\n\n\tconst nodeAfter = position.nodeAfter;\n\n\tif ( nodeAfter && nodeAfter.is( 'text' ) ) {\n\t\treturn new Position( nodeAfter, 0 );\n\t}\n\n\treturn position;\n}\n\n// Breaks text node into two text nodes when possible.\n//\n//\t\t<p>foo{}bar</p> -> <p>foo[]bar</p>\n//\t\t<p>{}foobar</p> -> <p>[]foobar</p>\n//\t\t<p>foobar{}</p> -> <p>foobar[]</p>\n//\n// @param {module:engine/view/position~Position} position Position that need to be placed inside text node.\n// @returns {module:engine/view/position~Position} New position after breaking text node.\nfunction breakTextNode( position ) {\n\tif ( position.offset == position.parent.data.length ) {\n\t\treturn new Position( position.parent.parent, position.parent.index + 1 );\n\t}\n\n\tif ( position.offset === 0 ) {\n\t\treturn new Position( position.parent.parent, position.parent.index );\n\t}\n\n\t// Get part of the text that need to be moved.\n\tconst textToMove = position.parent.data.slice( position.offset );\n\n\t// Leave rest of the text in position's parent.\n\tposition.parent.data = position.parent.data.slice( 0, position.offset );\n\n\t// Insert new text node after position's parent text node.\n\tposition.parent.parent.insertChildren( position.parent.index + 1, new Text( textToMove ) );\n\n\t// Return new position between two newly created text nodes.\n\treturn new Position( 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 {module:engine/view/text~Text} t1 First text node to merge. Data from second text node will be moved at the end of\n// this text node.\n// @param {module:engine/view/text~Text} t2 Second text node to merge. This node will be removed after merging.\n// @returns {module:engine/view/position~Position} Position after merging text nodes.\nfunction mergeTextNodes( t1, t2 ) {\n\t// Merge text data into first text node and remove second one.\n\tconst nodeBeforeLength = t1.data.length;\n\tt1.data += t2.data;\n\tt2.remove();\n\n\treturn new Position( t1, nodeBeforeLength );\n}\n\n// Wraps one {@link module:engine/view/attributeelement~AttributeElement AttributeElement} into another by merging them if possible.\n// When merging is possible - all attributes, styles and classes are moved from wrapper element to element being\n// wrapped.\n//\n// @param {module:engine/view/attributeelement~AttributeElement} wrapper Wrapper AttributeElement.\n// @param {module:engine/view/attributeelement~AttributeElement} toWrap AttributeElement to wrap using wrapper element.\n// @returns {Boolean} Returns `true` if elements are merged.\nfunction wrapAttributeElement( wrapper, toWrap ) {\n\t// Can't merge if name or priority differs.\n\tif ( wrapper.name !== toWrap.name || wrapper.priority !== toWrap.priority ) {\n\t\treturn false;\n\t}\n\n\t// Check if attributes can be merged.\n\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t// Classes and styles should be checked separately.\n\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// If some attributes are different we cannot wrap.\n\t\tif ( toWrap.hasAttribute( key ) && toWrap.getAttribute( key ) !== wrapper.getAttribute( key ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check if styles can be merged.\n\tfor ( const key of wrapper.getStyleNames() ) {\n\t\tif ( toWrap.hasStyle( key ) && toWrap.getStyle( key ) !== wrapper.getStyle( key ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Move all attributes/classes/styles from wrapper to wrapped AttributeElement.\n\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t// Classes and styles should be checked separately.\n\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Move only these attributes that are not present - other are similar.\n\t\tif ( !toWrap.hasAttribute( key ) ) {\n\t\t\ttoWrap.setAttribute( key, wrapper.getAttribute( key ) );\n\t\t}\n\t}\n\n\tfor ( const key of wrapper.getStyleNames() ) {\n\t\tif ( !toWrap.hasStyle( key ) ) {\n\t\t\ttoWrap.setStyle( key, wrapper.getStyle( key ) );\n\t\t}\n\t}\n\n\tfor ( const key of wrapper.getClassNames() ) {\n\t\tif ( !toWrap.hasClass( key ) ) {\n\t\t\ttoWrap.addClass( key );\n\t\t}\n\t}\n\n\treturn true;\n}\n\n// Unwraps {@link module:engine/view/attributeelement~AttributeElement AttributeElement} from another by removing corresponding attributes,\n// classes and styles. All attributes, classes and styles from wrapper should be present inside element being unwrapped.\n//\n// @param {module:engine/view/attributeelement~AttributeElement} wrapper Wrapper AttributeElement.\n// @param {module:engine/view/attributeelement~AttributeElement} toUnwrap AttributeElement to unwrap using wrapper element.\n// @returns {Boolean} Returns `true` if elements are unwrapped.\nfunction unwrapAttributeElement( wrapper, toUnwrap ) {\n\t// Can't unwrap if name or priority differs.\n\tif ( wrapper.name !== toUnwrap.name || wrapper.priority !== toUnwrap.priority ) {\n\t\treturn false;\n\t}\n\n\t// Check if AttributeElement has all wrapper attributes.\n\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t// Classes and styles should be checked separately.\n\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// If some attributes are missing or different we cannot unwrap.\n\t\tif ( !toUnwrap.hasAttribute( key ) || toUnwrap.getAttribute( key ) !== wrapper.getAttribute( key ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check if AttributeElement has all wrapper classes.\n\tif ( !toUnwrap.hasClass( ...wrapper.getClassNames() ) ) {\n\t\treturn false;\n\t}\n\n\t// Check if AttributeElement has all wrapper styles.\n\tfor ( const key of wrapper.getStyleNames() ) {\n\t\t// If some styles are missing or different we cannot unwrap.\n\t\tif ( !toUnwrap.hasStyle( key ) || toUnwrap.getStyle( key ) !== wrapper.getStyle( key ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Remove all wrapper's attributes from unwrapped element.\n\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t// Classes and styles should be checked separately.\n\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\ttoUnwrap.removeAttribute( key );\n\t}\n\n\t// Remove all wrapper's classes from unwrapped element.\n\ttoUnwrap.removeClass( ...wrapper.getClassNames() );\n\n\t// Remove all wrapper's styles from unwrapped element.\n\ttoUnwrap.removeStyle( ...wrapper.getStyleNames() );\n\n\treturn true;\n}\n\n// Returns `true` if range is located in same {@link module:engine/view/attributeelement~AttributeElement AttributeElement}\n// (`start` and `end` positions are located inside same {@link module:engine/view/attributeelement~AttributeElement AttributeElement}),\n// starts on 0 offset and ends after last child node.\n//\n// @param {module:engine/view/range~Range} Range\n// @returns {Boolean}\nfunction rangeSpansOnAllChildren( range ) {\n\treturn range.start.parent == range.end.parent && range.start.parent.is( 'attributeElement' ) &&\n\t\trange.start.offset === 0 && range.end.offset === range.start.parent.childCount;\n}\n\n// Checks if provided nodes are valid to insert. Checks if each node is an instance of\n// {@link module:engine/view/text~Text Text} or {@link module:engine/view/attributeelement~AttributeElement AttributeElement},\n// {@link module:engine/view/containerelement~ContainerElement ContainerElement},\n// {@link module:engine/view/emptyelement~EmptyElement EmptyElement} or\n// {@link module:engine/view/uielement~UIElement UIElement}.\n//\n// Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n// contains instances that are not {@link module:engine/view/text~Text Texts},\n// {@link module:engine/view/emptyelement~EmptyElement EmptyElements},\n// {@link module:engine/view/uielement~UIElement UIElements},\n// {@link module:engine/view/attributeelement~AttributeElement AttributeElements} or\n// {@link module:engine/view/containerelement~ContainerElement ContainerElements}.\n//\n// @param Iterable.<module:engine/view/text~Text|module:engine/view/attributeelement~AttributeElement\n// |module:engine/view/containerelement~ContainerElement> nodes\nfunction validateNodesToInsert( nodes ) {\n\tfor ( const node of nodes ) {\n\t\tif ( !validNodesToInsert.some( ( validNode => node instanceof validNode ) ) ) { // eslint-disable-line no-use-before-define\n\t\t\t/**\n\t\t\t * Inserted nodes should be valid to insert. of {@link module:engine/view/attributeelement~AttributeElement AttributeElement},\n\t\t\t * {@link module:engine/view/containerelement~ContainerElement ContainerElement},\n\t\t\t * {@link module:engine/view/emptyelement~EmptyElement EmptyElement},\n\t\t\t * {@link module:engine/view/uielement~UIElement UIElement}, {@link module:engine/view/text~Text Text}.\n\t\t\t *\n\t\t\t * @error view-writer-insert-invalid-node\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-insert-invalid-node' );\n\t\t}\n\n\t\tif ( !node.is( 'text' ) ) {\n\t\t\tvalidateNodesToInsert( node.getChildren() );\n\t\t}\n\t}\n}\n\nconst validNodesToInsert = [ Text, AttributeElement, ContainerElement, EmptyElement, UIElement ];\n\n// Checks if node is ContainerElement or DocumentFragment, because in most cases they should be treated the same way.\n//\n// @param {module:engine/view/node~Node} node\n// @returns {Boolean} Returns `true` if node is instance of ContainerElement or DocumentFragment.\nfunction isContainerOrFragment( node ) {\n\treturn node && ( node.is( 'containerElement' ) || node.is( 'documentFragment' ) );\n}\n\n// Checks if {@link module:engine/view/range~Range#start range start} and {@link module:engine/view/range~Range#end range end} are placed\n// inside same {@link module:engine/view/containerelement~ContainerElement container element}.\n// Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when validation fails.\n//\n// @param {module:engine/view/range~Range} range\nfunction validateRangeContainer( range ) {\n\tconst startContainer = getParentContainer( range.start );\n\tconst endContainer = getParentContainer( range.end );\n\n\tif ( !startContainer || !endContainer || startContainer !== endContainer ) {\n\t\t/**\n\t\t * Range container is invalid. This can happen if {@link module:engine/view/range~Range#start range start} and\n\t\t * {@link module:engine/view/range~Range#end range end} positions are not placed inside same container or\n\t\t * parent container for these positions cannot be found.\n\t\t *\n\t\t * @error view-writer-invalid-range-container\n\t\t */\n\t\tthrow new CKEditorError( 'view-writer-invalid-range-container' );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/writer.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport ViewElement from '../view/element';\nimport ViewAttributeElement from '../view/attributeelement';\nimport ViewText from '../view/text';\nimport ViewRange from '../view/range';\nimport ViewPosition from '../view/position';\nimport ViewTreeWalker from '../view/treewalker';\nimport viewWriter from '../view/writer';\nimport ModelRange from '../model/range';\n\n/**\n * Contains {@link module:engine/model/model model} to {@link module:engine/view/view view} converters for\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}.\n *\n * @module engine/conversion/model-to-view-converters\n */\n\n/**\n * Function factory, creates a converter that converts node insertion changes from the model to the view.\n * The view element that will be added to the view depends on passed parameter. If {@link module:engine/view/element~Element} was passed,\n * it will be cloned and the copy will be inserted. If `Function` is provided, it is passed all the parameters of the\n * dispatcher's {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:insert insert event}.\n * It's expected that the function returns a {@link module:engine/view/element~Element}.\n * The result of the function will be inserted to the view.\n *\n * The converter automatically consumes corresponding value from consumables list, stops the event (see\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}) and bind model and view elements.\n *\n *\t\tmodelDispatcher.on( 'insert:paragraph', insertElement( new ViewElement( 'p' ) ) );\n *\n *\t\tmodelDispatcher.on(\n *\t\t\t'insert:myElem',\n *\t\t\tinsertElement( ( data, consumable, conversionApi ) => {\n *\t\t\t\tlet myElem = new ViewElement( 'myElem', { myAttr: true }, new ViewText( 'myText' ) );\n *\n *\t\t\t\t// Do something fancy with myElem using data/consumable/conversionApi ...\n *\n *\t\t\t\treturn myElem;\n *\t\t\t}\n *\t\t) );\n *\n * @param {module:engine/view/element~Element|Function} elementCreator View element, or function returning a view element, which\n * will be inserted.\n * @returns {Function} Insert element event converter.\n */\nexport function insertElement( elementCreator ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst viewElement = ( elementCreator instanceof ViewElement ) ?\n\t\t\telementCreator.clone( true ) :\n\t\t\telementCreator( data, consumable, conversionApi );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !consumable.consume( data.item, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconversionApi.mapper.bindElements( data.item, viewElement );\n\t\tviewWriter.insert( viewPosition, viewElement );\n\t};\n}\n\n/**\n * Function factory, creates a default model-to-view converter for text insertion changes.\n *\n * The converter automatically consumes corresponding value from consumables list and stops the event (see\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}).\n *\n *\t\tmodelDispatcher.on( 'insert:$text', insertText() );\n *\n * @returns {Function} Insert text event converter.\n */\nexport function insertText() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tif ( !consumable.consume( data.item, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\t\tconst viewText = new ViewText( data.item.data );\n\n\t\tviewWriter.insert( viewPosition, viewText );\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts marker adding change to the view ui element.\n * The view ui element that will be added to the view depends on passed parameter. See {@link ~insertElement}.\n * In a case of collapsed range element will not wrap range but separate elements will be placed at the beginning\n * and at the end of the range.\n *\n * **Note:** unlike {@link ~insertElement}, the converter does not bind view element to model, because this converter\n * uses marker as \"model source of data\". This means that view ui element does not have corresponding model element.\n *\n * @param {module:engine/view/uielement~UIElement|Function} elementCreator View ui element, or function returning a view element, which\n * will be inserted.\n * @returns {Function} Insert element event converter.\n */\nexport function insertUIElement( elementCreator ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tlet viewStartElement, viewEndElement;\n\n\t\tif ( elementCreator instanceof ViewElement ) {\n\t\t\tviewStartElement = elementCreator.clone( true );\n\t\t\tviewEndElement = elementCreator.clone( true );\n\t\t} else {\n\t\t\tdata.isOpening = true;\n\t\t\tviewStartElement = elementCreator( data, consumable, conversionApi );\n\n\t\t\tdata.isOpening = false;\n\t\t\tviewEndElement = elementCreator( data, consumable, conversionApi );\n\t\t}\n\n\t\tif ( !viewStartElement || !viewEndElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst markerRange = data.markerRange;\n\t\tconst eventName = evt.name;\n\n\t\t// Marker that is collapsed has consumable build differently that non-collapsed one.\n\t\t// For more information see `addMarker` and `removeMarker` events description.\n\t\t// If marker's range is collapsed - check if it can be consumed.\n\t\tif ( markerRange.isCollapsed && !consumable.consume( markerRange, eventName ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If marker's range is not collapsed - consume all items inside.\n\t\tfor ( const value of markerRange ) {\n\t\t\tif ( !consumable.consume( value.item, eventName ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst mapper = conversionApi.mapper;\n\n\t\tviewWriter.insert( mapper.toViewPosition( markerRange.start ), viewStartElement );\n\n\t\tif ( !markerRange.isCollapsed ) {\n\t\t\tviewWriter.insert( mapper.toViewPosition( markerRange.end ), viewEndElement );\n\t\t}\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts set/change attribute changes from the model to the view. Attributes\n * from model are converted to the view element attributes in the view. You may provide a custom function to generate a\n * key-value attribute pair to add/change. If not provided, model attributes will be converted to view elements attributes\n * on 1-to-1 basis.\n *\n * **Note:** Provided attribute creator should always return the same `key` for given attribute from the model.\n *\n * The converter automatically consumes corresponding value from consumables list and stops the event (see\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}).\n *\n *\t\tmodelDispatcher.on( 'addAttribute:customAttr:myElem', setAttribute( ( data ) => {\n *\t\t\t// Change attribute key from `customAttr` to `class` in view.\n *\t\t\tconst key = 'class';\n *\t\t\tlet value = data.attributeNewValue;\n *\n *\t\t\t// Force attribute value to 'empty' if the model element is empty.\n *\t\t\tif ( data.item.childCount === 0 ) {\n *\t\t\t\tvalue = 'empty';\n *\t\t\t}\n *\n *\t\t\t// Return key-value pair.\n *\t\t\treturn { key, value };\n *\t\t} ) );\n *\n * @param {Function} [attributeCreator] Function returning an object with two properties: `key` and `value`, which\n * represents attribute key and attribute value to be set on a {@link module:engine/view/element~Element view element}.\n * The function is passed all the parameters of the\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:addAttribute}\n * or {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:changeAttribute} event.\n * @returns {Function} Set/change attribute converter.\n */\nexport function setAttribute( attributeCreator ) {\n\tattributeCreator = attributeCreator || ( ( value, key ) => ( { value, key } ) );\n\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tif ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { key, value } = attributeCreator( data.attributeNewValue, data.attributeKey, data, consumable, conversionApi );\n\n\t\tconversionApi.mapper.toViewElement( data.item ).setAttribute( key, value );\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts remove attribute changes from the model to the view. Removes attributes\n * that were converted to the view element attributes in the view. You may provide a custom function to generate a\n * key-value attribute pair to remove. If not provided, model attributes will be removed from view elements on 1-to-1 basis.\n *\n * **Note:** Provided attribute creator should always return the same `key` for given attribute from the model.\n *\n * **Note:** You can use the same attribute creator as in {@link module:engine/conversion/model-to-view-converters~setAttribute}.\n *\n * The converter automatically consumes corresponding value from consumables list and stops the event (see\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}).\n *\n *\t\tmodelDispatcher.on( 'removeAttribute:customAttr:myElem', removeAttribute( ( data ) => {\n *\t\t\t// Change attribute key from `customAttr` to `class` in view.\n *\t\t\tconst key = 'class';\n *\t\t\tlet value = data.attributeNewValue;\n *\n *\t\t\t// Force attribute value to 'empty' if the model element is empty.\n *\t\t\tif ( data.item.childCount === 0 ) {\n *\t\t\t\tvalue = 'empty';\n *\t\t\t}\n *\n *\t\t\t// Return key-value pair.\n *\t\t\treturn { key, value };\n *\t\t} ) );\n *\n * @param {Function} [attributeCreator] Function returning an object with two properties: `key` and `value`, which\n * represents attribute key and attribute value to be removed from {@link module:engine/view/element~Element view element}.\n * The function is passed all the parameters of the\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:addAttribute addAttribute event}\n * or {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:changeAttribute changeAttribute event}.\n * @returns {Function} Remove attribute converter.\n */\nexport function removeAttribute( attributeCreator ) {\n\tattributeCreator = attributeCreator || ( ( value, key ) => ( { key } ) );\n\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tif ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { key } = attributeCreator( data.attributeOldValue, data.attributeKey, data, consumable, conversionApi );\n\n\t\tconversionApi.mapper.toViewElement( data.item ).removeAttribute( key );\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts set/change attribute changes from the model to the view. In this case,\n * model attributes are converted to a view element that will be wrapping view nodes which corresponding model nodes had\n * the attribute set. This is useful for attributes like `bold`, which may be set on text nodes in model but are\n * represented as an element in the view:\n *\n *\t\t[paragraph] MODEL ====> VIEW <p>\n *\t\t\t|- a {bold: true} |- <b>\n *\t\t\t|- b {bold: true} | |- ab\n *\t\t\t|- c |- c\n *\n * The wrapping node depends on passed parameter. If {@link module:engine/view/element~Element} was passed, it will be cloned and\n * the copy will become the wrapping element. If `Function` is provided, it is passed attribute value and then all the parameters of the\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:addAttribute addAttribute event}.\n * It's expected that the function returns a {@link module:engine/view/element~Element}.\n * The result of the function will be the wrapping element.\n * When provided `Function` does not return element, then will be no conversion.\n *\n * The converter automatically consumes corresponding value from consumables list, stops the event (see\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}).\n *\n *\t\tmodelDispatcher.on( 'addAttribute:bold', wrapItem( new ViewAttributeElement( 'strong' ) ) );\n *\n * @param {module:engine/view/element~Element|Function} elementCreator View element, or function returning a view element, which will\n * be used for wrapping.\n * @returns {Function} Set/change attribute converter.\n */\nexport function wrapItem( elementCreator ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst viewElement = ( elementCreator instanceof ViewElement ) ?\n\t\t\telementCreator.clone( true ) :\n\t\t\telementCreator( data.attributeNewValue, data, consumable, conversionApi );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet viewRange = conversionApi.mapper.toViewRange( data.range );\n\n\t\t// If this is a change event (because old value is not empty) and the creator is a function (so\n\t\t// it may create different view elements basing on attribute value) we have to create\n\t\t// view element basing on old value and unwrap it before wrapping with a newly created view element.\n\t\tif ( data.attributeOldValue !== null && !( elementCreator instanceof ViewElement ) ) {\n\t\t\tconst oldViewElement = elementCreator( data.attributeOldValue, data, consumable, conversionApi );\n\t\t\tviewRange = viewWriter.unwrap( viewRange, oldViewElement );\n\t\t}\n\n\t\tviewWriter.wrap( viewRange, viewElement );\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts remove attribute changes from the model to the view. It assumes, that\n * attributes from model were converted to elements in the view. This converter will unwrap view nodes from corresponding\n * view element if given attribute was removed.\n *\n * The view element type that will be unwrapped depends on passed parameter.\n * If {@link module:engine/view/element~Element} was passed, it will be used to look for similar element in the view for unwrapping.\n * If `Function` is provided, it is passed all the parameters of the\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:addAttribute addAttribute event}.\n * It's expected that the function returns a {@link module:engine/view/element~Element}.\n * The result of the function will be used to look for similar element in the view for unwrapping.\n *\n * The converter automatically consumes corresponding value from consumables list, stops the event (see\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}) and bind model and view elements.\n *\n *\t\tmodelDispatcher.on( 'removeAttribute:bold', unwrapItem( new ViewAttributeElement( 'strong' ) ) );\n *\n * @see module:engine/conversion/model-to-view-converters~wrapItem\n * @param {module:engine/view/element~Element|Function} elementCreator View element, or function returning a view element, which will\n * be used for unwrapping.\n * @returns {Function} Remove attribute converter.\n */\nexport function unwrapItem( elementCreator ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst viewElement = ( elementCreator instanceof ViewElement ) ?\n\t\t\telementCreator.clone( true ) :\n\t\t\telementCreator( data.attributeOldValue, data, consumable, conversionApi );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewRange = conversionApi.mapper.toViewRange( data.range );\n\n\t\tviewWriter.unwrap( viewRange, viewElement );\n\t};\n}\n\n/**\n * Function factory, creates a default model-to-view converter for node remove changes.\n *\n *\t\tmodelDispatcher.on( 'remove', remove() );\n *\n * @returns {Function} Remove event converter.\n */\nexport function remove() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tif ( !consumable.consume( data.item, 'remove' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We cannot map non-existing positions from model to view. Since a range was removed\n\t\t// from the model, we cannot recreate that range and map it to view, because\n\t\t// end of that range is incorrect.\n\t\t// Instead we will use `data.sourcePosition` as this is the last correct model position and\n\t\t// it is a position before the removed item. Then, we will calculate view range to remove \"manually\".\n\t\tlet viewPosition = conversionApi.mapper.toViewPosition( data.sourcePosition );\n\t\tlet viewRange;\n\n\t\tif ( data.item.is( 'element' ) ) {\n\t\t\t// Note: in remove conversion we cannot use model-to-view element mapping because `data.item` may be\n\t\t\t// already mapped to another element (this happens when move change is converted).\n\t\t\t// In this case however, `viewPosition` is the position before view element that corresponds to removed model element.\n\t\t\t//\n\t\t\t// First, fix the position. Traverse the tree forward until the container element is found. The `viewPosition`\n\t\t\t// may be before a ui element, before attribute element or at the end of text element.\n\t\t\tviewPosition = viewPosition.getLastMatchingPosition( value => !value.item.is( 'containerElement' ) );\n\n\t\t\tif ( viewPosition.parent.is( 'text' ) && viewPosition.isAtEnd ) {\n\t\t\t\tviewPosition = ViewPosition.createAfter( viewPosition.parent );\n\t\t\t}\n\n\t\t\tviewRange = ViewRange.createOn( viewPosition.nodeAfter );\n\t\t} else {\n\t\t\t// If removed item is a text node, we need to traverse view tree to find the view range to remove.\n\t\t\t// Range to remove will start `viewPosition` and should contain amount of characters equal to the amount of removed characters.\n\t\t\tconst viewRangeEnd = _shiftViewPositionByCharacters( viewPosition, data.item.offsetSize );\n\t\t\tviewRange = new ViewRange( viewPosition, viewRangeEnd );\n\t\t}\n\n\t\t// Trim the range to remove in case some UI elements are on the view range boundaries.\n\t\tviewWriter.remove( viewRange.getTrimmed() );\n\n\t\t// Unbind this element only if it was moved to graveyard.\n\t\t// The dispatcher#remove event will also be fired if the element was moved to another place (remove+insert are fired).\n\t\t// Let's say that <b> is moved before <a>. The view will be changed like this:\n\t\t//\n\t\t// 1) start: <a></a><b></b>\n\t\t// 2) insert: <b (new)></b><a></a><b></b>\n\t\t// 3) remove: <b (new)></b><a></a>\n\t\t//\n\t\t// If we'll unbind the <b> element in step 3 we'll also lose binding of the <b (new)> element in the view,\n\t\t// because unbindModelElement() cancels both bindings (model <b> => view <b (new)>) and (view <b (new)> => model <b>).\n\t\t// We can't lose any of these.\n\t\t//\n\t\t// See #847.\n\t\tif ( data.item.root.rootName == '$graveyard' ) {\n\t\t\tconversionApi.mapper.unbindModelElement( data.item );\n\t\t}\n\t};\n}\n\n/**\n * Function factory, creates converter that converts all texts inside marker's range. Converter wraps each text with\n * {@link module:engine/view/attributeelement~AttributeElement} created from provided descriptor.\n * See {link module:engine/conversion/model-to-view-converters~highlightDescriptorToAttributeElement}.\n *\n * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor|Function} highlightDescriptor\n * @return {Function}\n */\nexport function highlightText( highlightDescriptor ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst descriptor = typeof highlightDescriptor == 'function' ?\n\t\t\thighlightDescriptor( data, consumable, conversionApi ) :\n\t\t\thighlightDescriptor;\n\n\t\tconst modelItem = data.item;\n\n\t\tif ( !descriptor || data.markerRange.isCollapsed || !modelItem.is( 'textProxy' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !consumable.consume( modelItem, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !descriptor.id ) {\n\t\t\tdescriptor.id = data.markerName;\n\t\t}\n\n\t\tconst viewElement = createViewElementFromHighlightDescriptor( descriptor );\n\t\tconst viewRange = conversionApi.mapper.toViewRange( data.range );\n\n\t\tif ( evt.name.split( ':' )[ 0 ] == 'addMarker' ) {\n\t\t\tviewWriter.wrap( viewRange, viewElement );\n\t\t} else {\n\t\t\tviewWriter.unwrap( viewRange, viewElement );\n\t\t}\n\t};\n}\n\n/**\n * Converter function factory. Creates a function which applies the marker's highlight to all elements inside a marker's range.\n * The converter checks if an element has the addHighlight and removeHighlight functions stored as\n * {@link module:engine/view/element~Element#setCustomProperty custom properties} and if so use them to apply the highlight.\n * In such case converter will consume all element's children, assuming that they were handled by element itself.\n * If the highlight descriptor will not provide priority, priority `10` will be used as default, to be compliant with\n * {@link module:engine/conversion/model-to-view-converters~highlightText} method which uses default priority of\n * {@link module:engine/view/attributeelement~AttributeElement}.\n *\n * If the highlight descriptor will not provide `id` property, name of the marker will be used.\n * When `addHighlight` and `removeHighlight` custom properties are not present, element is not converted\n * in any special way. This means that converters will proceed to convert element's child nodes.\n *\n * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor|Function} highlightDescriptor\n * @return {Function}\n */\nexport function highlightElement( highlightDescriptor ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst descriptor = typeof highlightDescriptor == 'function' ?\n\t\t\thighlightDescriptor( data, consumable, conversionApi ) :\n\t\t\thighlightDescriptor;\n\n\t\tconst modelItem = data.item;\n\n\t\tif ( !descriptor || data.markerRange.isCollapsed || !modelItem.is( 'element' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !consumable.test( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !descriptor.priority ) {\n\t\t\tdescriptor.priority = 10;\n\t\t}\n\n\t\tif ( !descriptor.id ) {\n\t\t\tdescriptor.id = data.markerName;\n\t\t}\n\n\t\tconst viewElement = conversionApi.mapper.toViewElement( modelItem );\n\t\tconst addMarker = evt.name.split( ':' )[ 0 ] == 'addMarker';\n\t\tconst highlightHandlingMethod = addMarker ? 'addHighlight' : 'removeHighlight';\n\n\t\tif ( viewElement && viewElement.getCustomProperty( highlightHandlingMethod ) ) {\n\t\t\t// Consume element itself.\n\t\t\tconsumable.consume( data.item, evt.name );\n\n\t\t\t// Consume all children nodes.\n\t\t\tfor ( const value of ModelRange.createIn( modelItem ) ) {\n\t\t\t\tconsumable.consume( value.item, evt.name );\n\t\t\t}\n\n\t\t\tviewElement.getCustomProperty( highlightHandlingMethod )( viewElement, addMarker ? descriptor : descriptor.id );\n\t\t}\n\t};\n}\n\n/**\n * Function factory, creates a default model-to-view converter for removing {@link module:engine/view/uielement~UIElement ui element}\n * basing on marker remove change.\n *\n * @param {module:engine/view/uielement~UIElement|Function} elementCreator View ui element, or function returning\n * a view ui element, which will be used as a pattern when look for element to remove at the marker start position.\n * @returns {Function} Remove ui element converter.\n */\nexport function removeUIElement( elementCreator ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tlet viewStartElement, viewEndElement;\n\n\t\tif ( elementCreator instanceof ViewElement ) {\n\t\t\tviewStartElement = elementCreator.clone( true );\n\t\t\tviewEndElement = elementCreator.clone( true );\n\t\t} else {\n\t\t\tdata.isOpening = true;\n\t\t\tviewStartElement = elementCreator( data, consumable, conversionApi );\n\n\t\t\tdata.isOpening = false;\n\t\t\tviewEndElement = elementCreator( data, consumable, conversionApi );\n\t\t}\n\n\t\tif ( !viewStartElement || !viewEndElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst markerRange = data.markerRange;\n\t\tconst eventName = evt.name;\n\n\t\t// If marker's range is collapsed - check if it can be consumed.\n\t\tif ( markerRange.isCollapsed && !consumable.consume( markerRange, eventName ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if all items in the range can be consumed, and consume them.\n\t\tfor ( const value of markerRange ) {\n\t\t\tif ( !consumable.consume( value.item, eventName ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst viewRange = conversionApi.mapper.toViewRange( markerRange );\n\n\t\t// First remove closing element.\n\t\tviewWriter.clear( viewRange.getEnlarged(), viewEndElement );\n\n\t\t// If closing and opening elements are not the same then remove opening element.\n\t\tif ( !viewStartElement.isSimilar( viewEndElement ) ) {\n\t\t\tviewWriter.clear( viewRange.getEnlarged(), viewStartElement );\n\t\t}\n\t};\n}\n\n/**\n * Returns the consumable type that is to be consumed in an event, basing on that event name.\n *\n * @param {String} evtName Event name.\n * @returns {String} Consumable type.\n */\nexport function eventNameToConsumableType( evtName ) {\n\tconst parts = evtName.split( ':' );\n\n\treturn parts[ 0 ] + ':' + parts[ 1 ];\n}\n\n// Helper function that shifts given view `position` in a way that returned position is after `howMany` characters compared\n// to the original `position`.\n// Because in view there might be view ui elements splitting text nodes, we cannot simply use `ViewPosition#getShiftedBy()`.\nfunction _shiftViewPositionByCharacters( position, howMany ) {\n\t// Create a walker that will walk the view tree starting from given position and walking characters one-by-one.\n\tconst walker = new ViewTreeWalker( { startPosition: position, singleCharacters: true } );\n\t// We will count visited characters and return the position after `howMany` characters.\n\tlet charactersFound = 0;\n\n\tfor ( const value of walker ) {\n\t\tif ( value.type == 'text' ) {\n\t\t\tcharactersFound++;\n\n\t\t\tif ( charactersFound == howMany ) {\n\t\t\t\treturn walker.position;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Creates `span` {@link module:engine/view/attributeelement~AttributeElement view attribute element} from information\n * provided by {@link module:engine/conversion/model-to-view-converters~HighlightDescriptor} object. If priority\n * is not provided in descriptor - default priority will be used.\n *\n * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} descriptor\n * @return {module:engine/conversion/model-to-view-converters~HighlightAttributeElement}\n */\nexport function createViewElementFromHighlightDescriptor( descriptor ) {\n\tconst viewElement = new HighlightAttributeElement( 'span', descriptor.attributes );\n\n\tif ( descriptor.class ) {\n\t\tconst cssClasses = Array.isArray( descriptor.class ) ? descriptor.class : [ descriptor.class ];\n\t\tviewElement.addClass( ...cssClasses );\n\t}\n\n\tif ( descriptor.priority ) {\n\t\tviewElement.priority = descriptor.priority;\n\t}\n\n\tviewElement.setCustomProperty( 'highlightDescriptorId', descriptor.id );\n\n\treturn viewElement;\n}\n\n/**\n * Special kind of {@link module:engine/view/attributeelement~AttributeElement} that is created and used in\n * marker-to-highlight conversion.\n *\n * The difference between `HighlightAttributeElement` and {@link module:engine/view/attributeelement~AttributeElement}\n * is {@link module:engine/view/attributeelement~AttributeElement#isSimilar} method.\n *\n * For `HighlightAttributeElement` it checks just `highlightDescriptorId` custom property, that is set during marker-to-highlight\n * conversion basing on {@link module:engine/conversion/model-to-view-converters~HighlightDescriptor} object.\n * `HighlightAttributeElement`s with same `highlightDescriptorId` property are considered similar.\n */\nclass HighlightAttributeElement extends ViewAttributeElement {\n\tisSimilar( otherElement ) {\n\t\tif ( otherElement.is( 'attributeElement' ) ) {\n\t\t\treturn this.getCustomProperty( 'highlightDescriptorId' ) === otherElement.getCustomProperty( 'highlightDescriptorId' );\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\n/**\n * Object describing how the content highlight should be created in the view.\n *\n * Each text node contained in the highlight will be wrapped with `span` element with CSS class(es), attributes and priority\n * described by this object.\n *\n * Each element can handle displaying the highlight separately by providing `addHighlight` and `removeHighlight` custom\n * properties:\n * * `HighlightDescriptor` is passed to the `addHighlight` function upon conversion and should be used to apply the highlight to\n * the element,\n * * descriptor id is passed to the `removeHighlight` function upon conversion and should be used to remove the highlight of given\n * id from the element.\n *\n * @typedef {Object} module:engine/conversion/model-to-view-converters~HighlightDescriptor\n *\n * @property {String|Array.<String>} class CSS class or array of classes to set. If descriptor is used to\n * create {@link module:engine/view/attributeelement~AttributeElement} over text nodes, those classes will be set\n * on that {@link module:engine/view/attributeelement~AttributeElement}. If descriptor is applied to an element,\n * usually those class will be set on that element, however this depends on how the element converts the descriptor.\n *\n * @property {String} [id] Descriptor identifier. If not provided, defaults to converted marker's name.\n *\n * @property {Number} [priority] Descriptor priority. If not provided, defaults to `10`. If descriptor is used to create\n * {@link module:engine/view/attributeelement~AttributeElement}, it will be that element's\n * {@link module:engine/view/attributeelement~AttributeElement#priority}. If descriptor is applied to an element,\n * the priority will be used to determine which descriptor is more important.\n *\n * @property {Object} [attributes] Attributes to set. If descriptor is used to create\n * {@link module:engine/view/attributeelement~AttributeElement} over text nodes, those attributes will be set on that\n * {@link module:engine/view/attributeelement~AttributeElement}. If descriptor is applied to an element, usually those\n * attributes will be set on that element, however this depends on how the element converts the descriptor.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/model-to-view-converters.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/writer\n */\n\nimport Node from './node';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport Range from './range';\nimport DocumentFragment from './documentfragment';\nimport NodeList from './nodelist';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Contains functions used for composing model tree, grouped together under \"model writer\" name. Those functions\n * are built on top of {@link module:engine/model/node~Node node}, and it's child classes', APIs.\n *\n * Model writer API has multiple advantages and it is highly recommended to use it when changing model tree and nodes:\n * * model writer API {@link module:engine/model/writer~writer.normalizeNodes normalizes inserted nodes}, which means that you can insert\n * not only {@link module:engine/model/node~Node nodes}, but also `String`s, {@link module:engine/model/textproxy~TextProxy text proxies}\n * and\n * {@link module:engine/model/documentfragment~DocumentFragment document fragments},\n * * model writer API operates on {@link module:engine/model/position~Position positions}, which means that you have\n * better control over manipulating model tree as positions operate on offsets rather than indexes,\n * * model writer API automatically merges {@link module:engine/model/text~Text text nodes} with same attributes, which means\n * lower memory usage and better efficiency.\n *\n * @namespace writer\n */\nconst writer = {\n\tinsert,\n\tremove,\n\tmove,\n\tsetAttribute,\n\tremoveAttribute,\n\tnormalizeNodes\n};\n\nexport default writer;\n\n/**\n * Inserts given nodes at given position.\n *\n * @function module:engine/model/writer~writer.insert\n * @param {module:engine/model/position~Position} position Position at which nodes should be inserted.\n * @param {module:engine/model/node~NodeSet} nodes Nodes to insert.\n * @returns {module:engine/model/range~Range} Range spanning over inserted elements.\n */\nexport function insert( position, nodes ) {\n\tnodes = normalizeNodes( nodes );\n\n\t// We have to count offset before inserting nodes because they can get merged and we would get wrong offsets.\n\tconst offset = nodes.reduce( ( sum, node ) => sum + node.offsetSize, 0 );\n\tconst parent = position.parent;\n\n\t// Insertion might be in a text node, we should split it if that's the case.\n\t_splitNodeAtPosition( position );\n\tconst index = position.index;\n\n\t// Insert nodes at given index. After splitting we have a proper index and insertion is between nodes,\n\t// using basic `Element` API.\n\tparent.insertChildren( index, nodes );\n\n\t// Merge text nodes, if possible. Merging is needed only at points where inserted nodes \"touch\" \"old\" nodes.\n\t_mergeNodesAtIndex( parent, index + nodes.length );\n\t_mergeNodesAtIndex( parent, index );\n\n\treturn new Range( position, position.getShiftedBy( offset ) );\n}\n\n/**\n * Removed nodes in given range. Only {@link module:engine/model/range~Range#isFlat flat} ranges are accepted.\n *\n * @function module:engine/model/writer~writer.remove\n * @param {module:engine/model/range~Range} range Range containing nodes to remove.\n * @returns {Array.<module:engine/model/node~Node>}\n */\nexport function remove( range ) {\n\tif ( !range.isFlat ) {\n\t\t/**\n\t\t * Trying to remove a range which starts and ends in different element.\n\t\t *\n\t\t * @error model-writer-remove-range-not-flat\n\t\t */\n\t\tthrow new CKEditorError( 'model-writer-remove-range-not-flat: ' +\n\t\t\t'Trying to remove a range which starts and ends in different element.' );\n\t}\n\n\tconst parent = range.start.parent;\n\n\t// Range may be inside text nodes, we have to split them if that's the case.\n\t_splitNodeAtPosition( range.start );\n\t_splitNodeAtPosition( range.end );\n\n\t// Remove the text nodes using basic `Element` API.\n\tconst removed = parent.removeChildren( range.start.index, range.end.index - range.start.index );\n\n\t// Merge text nodes, if possible. After some nodes were removed, node before and after removed range will be\n\t// touching at the position equal to the removed range beginning. We check merging possibility there.\n\t_mergeNodesAtIndex( parent, range.start.index );\n\n\treturn removed;\n}\n\n/**\n * Moves nodes in given range to given target position. Only {@link module:engine/model/range~Range#isFlat flat} ranges are accepted.\n *\n * @param {module:engine/model/range~Range} sourceRange Range containing nodes to move.\n * @param {module:engine/model/position~Position} targetPosition Position to which nodes should be moved.\n * @returns {module:engine/model/range~Range} Range containing moved nodes.\n */\nexport function move( sourceRange, targetPosition ) {\n\tif ( !sourceRange.isFlat ) {\n\t\t/**\n\t\t * Trying to move a range which starts and ends in different element.\n\t\t *\n\t\t * @error model-writer-move-range-not-flat\n\t\t */\n\t\tthrow new CKEditorError( 'model-writer-move-range-not-flat: ' +\n\t\t\t'Trying to move a range which starts and ends in different element.' );\n\t}\n\n\tconst nodes = this.remove( sourceRange );\n\n\t// We have to fix `targetPosition` because model changed after nodes from `sourceRange` got removed and\n\t// that change might have an impact on `targetPosition`.\n\ttargetPosition = targetPosition._getTransformedByDeletion( sourceRange.start, sourceRange.end.offset - sourceRange.start.offset );\n\n\treturn this.insert( targetPosition, nodes );\n}\n\n/**\n * Sets given attribute on nodes in given range.\n *\n * @param {module:engine/model/range~Range} range Range containing nodes that should have the attribute set.\n * @param {String} key Key of attribute to set.\n * @param {*} value Attribute value.\n */\nexport function setAttribute( range, key, value ) {\n\t// Range might start or end in text nodes, so we have to split them.\n\t_splitNodeAtPosition( range.start );\n\t_splitNodeAtPosition( range.end );\n\n\t// Iterate over all items in the range.\n\tfor ( const item of range.getItems() ) {\n\t\t// Iterator will return `TextProxy` instances but we know that those text proxies will\n\t\t// always represent full text nodes (this is guaranteed thanks to splitting we did before).\n\t\t// So, we can operate on those text proxies' text nodes.\n\t\tconst node = item.is( 'textProxy' ) ? item.textNode : item;\n\n\t\tif ( value !== null ) {\n\t\t\tnode.setAttribute( key, value );\n\t\t} else {\n\t\t\tnode.removeAttribute( key );\n\t\t}\n\n\t\t// After attributes changing it may happen that some text nodes can be merged. Try to merge with previous node.\n\t\t_mergeNodesAtIndex( node.parent, node.index );\n\t}\n\n\t// Try to merge last changed node with it's previous sibling (not covered by the loop above).\n\t_mergeNodesAtIndex( range.end.parent, range.end.index );\n}\n\n/**\n * Removes given attribute from nodes in given range.\n *\n * @param {module:engine/model/range~Range} range Range containing nodes that should have the attribute removed.\n * @param {String} key Key of attribute to remove.\n */\nexport function removeAttribute( range, key ) {\n\tthis.setAttribute( range, key, null );\n}\n\n/**\n * Normalizes given object or an array of objects to an array of {@link module:engine/model/node~Node nodes}. See\n * {@link module:engine/model/node~NodeSet NodeSet} for details on how normalization is performed.\n *\n * @param {module:engine/model/node~NodeSet} nodes Objects to normalize.\n * @returns {Array.<module:engine/model/node~Node>} Normalized nodes.\n */\nexport function normalizeNodes( nodes ) {\n\tconst normalized = [];\n\n\tif ( !( nodes instanceof Array ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Convert instances of classes other than Node.\n\tfor ( let i = 0; i < nodes.length; i++ ) {\n\t\tif ( typeof nodes[ i ] == 'string' ) {\n\t\t\tnormalized.push( new Text( nodes[ i ] ) );\n\t\t} else if ( nodes[ i ] instanceof TextProxy ) {\n\t\t\tnormalized.push( new Text( nodes[ i ].data, nodes[ i ].getAttributes() ) );\n\t\t} else if ( nodes[ i ] instanceof DocumentFragment || nodes[ i ] instanceof NodeList ) {\n\t\t\tfor ( const child of nodes[ i ] ) {\n\t\t\t\tnormalized.push( child );\n\t\t\t}\n\t\t} else if ( nodes[ i ] instanceof Node ) {\n\t\t\tnormalized.push( nodes[ i ] );\n\t\t}\n\t\t// Skip unrecognized type.\n\t}\n\n\t// Merge text nodes.\n\tfor ( let i = 1; i < normalized.length; i++ ) {\n\t\tconst node = normalized[ i ];\n\t\tconst prev = normalized[ i - 1 ];\n\n\t\tif ( node instanceof Text && prev instanceof Text && _haveSameAttributes( node, prev ) ) {\n\t\t\t// Doing this instead changing prev.data because .data is readonly.\n\t\t\tnormalized.splice( i - 1, 2, new Text( prev.data + node.data, prev.getAttributes() ) );\n\t\t\ti--;\n\t\t}\n\t}\n\n\treturn normalized;\n}\n\n/**\n * Checks if nodes before and after given index in given element are {@link module:engine/model/text~Text 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 * @ignore\n * @private\n * @param {module:engine/model/element~Element} element Parent element of nodes to merge.\n * @param {Number} 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\n\t// Check if both of those nodes are text objects with same attributes.\n\tif ( nodeBefore && nodeAfter && nodeBefore.is( 'text' ) && nodeAfter.is( 'text' ) && _haveSameAttributes( nodeBefore, nodeAfter ) ) {\n\t\t// Append text of text node after index to the before one.\n\t\tconst mergedNode = new Text( nodeBefore.data + nodeAfter.data, nodeBefore.getAttributes() );\n\n\t\t// Remove separate text nodes.\n\t\telement.removeChildren( index - 1, 2 );\n\n\t\t// Insert merged text node.\n\t\telement.insertChildren( index - 1, mergedNode );\n\t}\n}\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 * @ignore\n * @private\n * @param {module:engine/model/position~Position} position Position at which node should be split.\n */\nfunction _splitNodeAtPosition( position ) {\n\tconst textNode = position.textNode;\n\tconst element = position.parent;\n\n\tif ( textNode ) {\n\t\tconst offsetDiff = position.offset - textNode.startOffset;\n\t\tconst index = textNode.index;\n\n\t\telement.removeChildren( index, 1 );\n\n\t\tconst firstPart = new Text( textNode.data.substr( 0, offsetDiff ), textNode.getAttributes() );\n\t\tconst secondPart = new Text( textNode.data.substr( offsetDiff ), textNode.getAttributes() );\n\n\t\telement.insertChildren( index, [ firstPart, secondPart ] );\n\t}\n}\n\n/**\n * Checks whether two given nodes have same attributes.\n *\n * @ignore\n * @private\n * @param {module:engine/model/node~Node} nodeA Node to check.\n * @param {module:engine/model/node~Node} nodeB Node to check.\n * @returns {Boolean} `true` if nodes have same attributes, `false` otherwise.\n */\nfunction _haveSameAttributes( nodeA, nodeB ) {\n\tconst iteratorA = nodeA.getAttributes();\n\tconst iteratorB = nodeB.getAttributes();\n\n\tfor ( const attr of iteratorA ) {\n\t\tif ( attr[ 1 ] !== nodeB.getAttribute( attr[ 0 ] ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\titeratorB.next();\n\t}\n\n\treturn iteratorB.next().done;\n}\n\n/**\n * Value that can be normalized to an array of {@link module:engine/model/node~Node nodes}.\n *\n * Non-arrays are normalized as follows:\n * * {@link module:engine/model/node~Node Node} is left as is,\n * * {@link module:engine/model/textproxy~TextProxy TextProxy} and `String` are normalized to {@link module:engine/model/text~Text Text},\n * * {@link module:engine/model/nodelist~NodeList NodeList} is normalized to an array containing all nodes that are in that node list,\n * * {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment} is normalized to an array containing all of it's\n * * children.\n *\n * Arrays are processed item by item like non-array values and flattened to one array. Normalization always results in\n * a flat array of {@link module:engine/model/node~Node nodes}. Consecutive text nodes (or items normalized to text nodes) will be\n * merged if they have same attributes.\n *\n * @typedef {module:engine/model/node~Node|module:engine/model/textproxy~TextProxy|String|\n * module:engine/model/nodelist~NodeList|module:engine/model/documentfragment~DocumentFragment|Iterable}\n * module:engine/model/node~NodeSet\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/writer.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/viewconversiondispatcher\n */\n\nimport ViewConsumable from './viewconsumable';\nimport ModelRange from '../model/range';\nimport ModelPosition from '../model/position';\nimport ModelTreeWalker from '../model/treewalker';\nimport ModelNode from '../model/node';\nimport ModelDocumentFragment from '../model/documentfragment';\nimport { remove } from '../model/writer';\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport extend from '@ckeditor/ckeditor5-utils/src/lib/lodash/extend';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\n/**\n * `ViewConversionDispatcher` is a central point of {@link module:engine/view/view view} conversion, which is a process of\n * converting given {@link module:engine/view/documentfragment~DocumentFragment view document fragment} or\n * {@link module:engine/view/element~Element}\n * into another structure. In default application, {@link module:engine/view/view view} is converted to {@link module:engine/model/model}.\n *\n * During conversion process, for all {@link module:engine/view/node~Node view nodes} from the converted view document fragment,\n * `ViewConversionDispatcher` fires corresponding events. Special callbacks called \"converters\" should listen to\n * `ViewConversionDispatcher` for those events.\n *\n * Each callback, as a first argument, is passed a special object `data` that has `input` and `output` properties.\n * `input` property contains {@link module:engine/view/node~Node view node} or\n * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}\n * that is converted at the moment and might be handled by the callback. `output` property should be used to save the result\n * of conversion. Keep in mind that the `data` parameter is customizable and may contain other values - see\n * {@link ~ViewConversionDispatcher#convert}. It is also shared by reference by all callbacks\n * listening to given event. **Note**: in view to model conversion - `data` contains `context` property that is an array\n * of {@link module:engine/model/element~Element model elements}. These are model elements that will be the parent of currently\n * converted view item. `context` property is used in examples below.\n *\n * The second parameter passed to a callback is an instance of {@link module:engine/conversion/viewconsumable~ViewConsumable}. It stores\n * information about what parts of processed view item are still waiting to be handled. After a piece of view item\n * was converted, appropriate consumable value should be {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consumed}.\n *\n * The third parameter passed to a callback is an instance of {@link ~ViewConversionDispatcher}\n * which provides additional tools for converters.\n *\n * Examples of providing callbacks for `ViewConversionDispatcher`:\n *\n *\t\t// Converter for paragraphs (<p>).\n *\t\tviewDispatcher.on( 'element:p', ( evt, data, consumable, conversionApi ) => {\n *\t\t\tconst paragraph = new ModelElement( 'paragraph' );\n *\t\t\tconst schemaQuery = {\n *\t\t\t\tname: 'paragraph',\n *\t\t\t\tinside: data.context\n *\t\t\t};\n *\n *\t\t\tif ( conversionApi.schema.check( schemaQuery ) ) {\n *\t\t\t\tif ( !consumable.consume( data.input, { name: true } ) ) {\n *\t\t\t\t\t// Before converting this paragraph's children we have to update their context by this paragraph.\n *\t\t\t\t\tdata.context.push( paragraph );\n *\t\t\t\t\tconst children = conversionApi.convertChildren( data.input, consumable, data );\n *\t\t\t\t\tdata.context.pop();\n *\t\t\t\t\tparagraph.appendChildren( children );\n *\t\t\t\t\tdata.output = paragraph;\n *\t\t\t\t}\n *\t\t\t}\n *\t\t} );\n *\n *\t\t// Converter for links (<a>).\n *\t\tviewDispatcher.on( 'element:a', ( evt, data, consumable, conversionApi ) => {\n *\t\t\tif ( consumable.consume( data.input, { name: true, attributes: [ 'href' ] } ) ) {\n *\t\t\t\t// <a> element is inline and is represented by an attribute in the model.\n *\t\t\t\t// This is why we are not updating `context` property.\n *\t\t\t\tdata.output = conversionApi.convertChildren( data.input, consumable, data );\n *\n *\t\t\t\tfor ( let item of Range.createFrom( data.output ) ) {\n *\t\t\t\t\tconst schemaQuery = {\n *\t\t\t\t\t\tname: item.name || '$text',\n *\t\t\t\t\t\tattribute: 'link',\n *\t\t\t\t\t\tinside: data.context\n *\t\t\t\t\t};\n *\n *\t\t\t\t\tif ( conversionApi.schema.check( schemaQuery ) ) {\n *\t\t\t\t\t\titem.setAttribute( 'link', data.input.getAttribute( 'href' ) );\n *\t\t\t\t\t}\n *\t\t\t\t}\n *\t\t\t}\n *\t\t} );\n *\n *\t\t// Fire conversion.\n *\t\t// Always take care where the converted model structure will be appended to. If this `viewDocumentFragment`\n *\t\t// is going to be appended directly to a '$root' element, use that in `context`.\n *\t\tviewDispatcher.convert( viewDocumentFragment, { context: [ '$root' ] } );\n *\n * Before each conversion process, `ViewConversionDispatcher` fires {@link ~ViewConversionDispatcher#event:viewCleanup}\n * event which can be used to prepare tree view for conversion.\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n * @fires viewCleanup\n * @fires element\n * @fires text\n * @fires documentFragment\n */\nexport default class ViewConversionDispatcher {\n\t/**\n\t * Creates a `ViewConversionDispatcher` that operates using passed API.\n\t *\n\t * @see module:engine/conversion/viewconversiondispatcher~ViewConversionApi\n\t * @param {Object} [conversionApi] Additional properties for interface that will be passed to events fired\n\t * by `ViewConversionDispatcher`.\n\t */\n\tconstructor( conversionApi = {} ) {\n\t\t/**\n\t\t * Interface passed by dispatcher to the events callbacks.\n\t\t *\n\t\t * @member {module:engine/conversion/viewconversiondispatcher~ViewConversionApi}\n\t\t */\n\t\tthis.conversionApi = extend( {}, conversionApi );\n\n\t\t// `convertItem` and `convertChildren` are bound to this `ViewConversionDispatcher` instance and\n\t\t// set on `conversionApi`. This way only a part of `ViewConversionDispatcher` API is exposed.\n\t\tthis.conversionApi.convertItem = this._convertItem.bind( this );\n\t\tthis.conversionApi.convertChildren = this._convertChildren.bind( this );\n\t}\n\n\t/**\n\t * Starts the conversion process. The entry point for the conversion.\n\t *\n\t * @fires element\n\t * @fires text\n\t * @fires documentFragment\n\t * @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/element~Element} viewItem\n\t * Part of the view to be converted.\n\t * @param {Object} [additionalData] Additional data to be passed in `data` argument when firing `ViewConversionDispatcher`\n\t * events. See also {@link ~ViewConversionDispatcher#event:element element event}.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Model data that is a result of the conversion process\n\t * wrapped in `DocumentFragment`. Converted marker elements will be set as that document fragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t */\n\tconvert( viewItem, additionalData = {} ) {\n\t\tthis.fire( 'viewCleanup', viewItem );\n\n\t\tconst consumable = ViewConsumable.createFrom( viewItem );\n\t\tlet conversionResult = this._convertItem( viewItem, consumable, additionalData );\n\n\t\t// We can get a null here if conversion failed (see _convertItem())\n\t\t// or simply if an item could not be converted (e.g. due to the schema).\n\t\tif ( !conversionResult ) {\n\t\t\treturn new ModelDocumentFragment();\n\t\t}\n\n\t\t// When conversion result is not a document fragment we need to wrap it in document fragment.\n\t\tif ( !conversionResult.is( 'documentFragment' ) ) {\n\t\t\tconversionResult = new ModelDocumentFragment( [ conversionResult ] );\n\t\t}\n\n\t\t// Extract temporary markers elements from model and set as static markers collection.\n\t\tconversionResult.markers = extractMarkersFromModelFragment( conversionResult );\n\n\t\treturn conversionResult;\n\t}\n\n\t/**\n\t * @private\n\t * @see module:engine/conversion/viewconversiondispatcher~ViewConversionApi#convertItem\n\t */\n\t_convertItem( input, consumable, additionalData = {} ) {\n\t\tconst data = extend( {}, additionalData, {\n\t\t\tinput,\n\t\t\toutput: null\n\t\t} );\n\n\t\tif ( input.is( 'element' ) ) {\n\t\t\tthis.fire( 'element:' + input.name, data, consumable, this.conversionApi );\n\t\t} else if ( input.is( 'text' ) ) {\n\t\t\tthis.fire( 'text', data, consumable, this.conversionApi );\n\t\t} else {\n\t\t\tthis.fire( 'documentFragment', data, consumable, this.conversionApi );\n\t\t}\n\n\t\t// Handle incorrect `data.output`.\n\t\tif ( data.output && !( data.output instanceof ModelNode || data.output instanceof ModelDocumentFragment ) ) {\n\t\t\t/**\n\t\t\t * Incorrect conversion result was dropped.\n\t\t\t *\n\t\t\t * Item may be converted to either {@link module:engine/model/node~Node model node} or\n\t\t\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment}.\n\t\t\t *\n\t\t\t * @error view-conversion-dispatcher-incorrect-result\n\t\t\t */\n\t\t\tlog.warn( 'view-conversion-dispatcher-incorrect-result: Incorrect conversion result was dropped.', [ input, data.output ] );\n\n\t\t\treturn null;\n\t\t}\n\n\t\treturn data.output;\n\t}\n\n\t/**\n\t * @private\n\t * @see module:engine/conversion/viewconversiondispatcher~ViewConversionApi#convertChildren\n\t */\n\t_convertChildren( input, consumable, additionalData = {} ) {\n\t\t// Get all children of view input item.\n\t\tconst viewChildren = Array.from( input.getChildren() );\n\n\t\t// 1. Map those children to model.\n\t\t// 2. Filter out items that has not been converted or for which conversion returned wrong result (for those warning is logged).\n\t\t// 3. Extract children from document fragments to flatten results.\n\t\tconst convertedChildren = viewChildren\n\t\t\t.map( viewChild => this._convertItem( viewChild, consumable, additionalData ) )\n\t\t\t.filter( converted => converted instanceof ModelNode || converted instanceof ModelDocumentFragment )\n\t\t\t.reduce( ( result, filtered ) => {\n\t\t\t\treturn result.concat(\n\t\t\t\t\tfiltered.is( 'documentFragment' ) ? Array.from( filtered.getChildren() ) : filtered\n\t\t\t\t);\n\t\t\t}, [] );\n\n\t\t// Normalize array to model document fragment.\n\t\treturn new ModelDocumentFragment( convertedChildren );\n\t}\n\n\t/**\n\t * Fired before the first conversion event, at the beginning of view to model conversion process.\n\t *\n\t * @event viewCleanup\n\t * @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/element~Element}\n\t * viewItem Part of the view to be converted.\n\t */\n\n\t/**\n\t * Fired when {@link module:engine/view/element~Element} is converted.\n\t *\n\t * `element` is a namespace event for a class of events. Names of actually called events follow this pattern:\n\t * `element:<elementName>` where `elementName` is the name of converted element. This way listeners may listen to\n\t * all elements conversion or to conversion of specific elements.\n\t *\n\t * @event element\n\t * @param {Object} data Object containing conversion input and a placeholder for conversion output and possibly other\n\t * values (see {@link #convert}).\n\t * Keep in mind that this object is shared by reference between all callbacks that will be called.\n\t * This means that callbacks can add their own values if needed,\n\t * and those values will be available in other callbacks.\n\t * @param {module:engine/view/element~Element} data.input Converted element.\n\t * @param {*} data.output The current state of conversion result. Every change to converted element should\n\t * be reflected by setting or modifying this property.\n\t * @param {module:engine/model/schema~SchemaPath} data.context The conversion context.\n\t * @param {module:engine/conversion/viewconsumable~ViewConsumable} consumable Values to consume.\n\t * @param {Object} conversionApi Conversion interface to be used by callback, passed in `ViewConversionDispatcher` constructor.\n\t * Besides of properties passed in constructor, it also has `convertItem` and `convertChildren` methods which are references\n\t * to {@link #_convertItem} and\n\t * {@link ~ViewConversionDispatcher#_convertChildren}. Those methods are needed to convert\n\t * the whole view-tree they were exposed in `conversionApi` for callbacks.\n\t */\n\n\t/**\n\t * Fired when {@link module:engine/view/text~Text} is converted.\n\t *\n\t * @event text\n\t * @see #event:element\n\t */\n\n\t/**\n\t * Fired when {@link module:engine/view/documentfragment~DocumentFragment} is converted.\n\t *\n\t * @event documentFragment\n\t * @see #event:element\n\t */\n}\n\nmix( ViewConversionDispatcher, EmitterMixin );\n\n// Traverses given model item and searches elements which marks marker range. Found element is removed from\n// DocumentFragment but path of this element is stored in a Map which is then returned.\n//\n// @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/node~Node} modelItem Fragment of model.\n// @returns {Map<String, module:engine/model/range~Range>} List of static markers.\nfunction extractMarkersFromModelFragment( modelItem ) {\n\tconst markerElements = new Set();\n\tconst markers = new Map();\n\n\t// Create ModelTreeWalker.\n\tconst walker = new ModelTreeWalker( {\n\t\tstartPosition: ModelPosition.createAt( modelItem, 0 ),\n\t\tignoreElementEnd: true\n\t} );\n\n\t// Walk through DocumentFragment and collect marker elements.\n\tfor ( const value of walker ) {\n\t\t// Check if current element is a marker.\n\t\tif ( value.item.name == '$marker' ) {\n\t\t\tmarkerElements.add( value.item );\n\t\t}\n\t}\n\n\t// Walk through collected marker elements store its path and remove its from the DocumentFragment.\n\tfor ( const markerElement of markerElements ) {\n\t\tconst markerName = markerElement.getAttribute( 'data-name' );\n\t\tconst currentPosition = ModelPosition.createBefore( markerElement );\n\n\t\t// When marker of given name is not stored it means that we have found the beginning of the range.\n\t\tif ( !markers.has( markerName ) ) {\n\t\t\tmarkers.set( markerName, new ModelRange( ModelPosition.createFromPosition( currentPosition ) ) );\n\t\t// Otherwise is means that we have found end of the marker range.\n\t\t} else {\n\t\t\tmarkers.get( markerName ).end = ModelPosition.createFromPosition( currentPosition );\n\t\t}\n\n\t\t// Remove marker element from DocumentFragment.\n\t\tremove( ModelRange.createOn( markerElement ) );\n\t}\n\n\treturn markers;\n}\n\n/**\n * Conversion interface that is registered for given {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher}\n * and is passed as one of parameters when {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher dispatcher}\n * fires it's events.\n *\n * `ViewConversionApi` object is built by {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher} constructor.\n * The exact list of properties of this object is determined by the object passed to the constructor.\n *\n * @interface ViewConversionApi\n */\n\n/**\n * Starts conversion of given item by firing an appropriate event.\n *\n * Every fired event is passed (as first parameter) an object with `output` property. Every event may set and/or\n * modify that property. When all callbacks are done, the final value of `output` property is returned by this method.\n * The `output` must be either {@link module:engine/model/node~Node model node} or\n * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} or `null` (as set by default).\n *\n * @method #convertItem\n * @fires module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:element\n * @fires module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:text\n * @fires module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:documentFragment\n * @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/element~Element|module:engine/view/text~Text}\n * input Item to convert.\n * @param {module:engine/conversion/viewconsumable~ViewConsumable} consumable Values to consume.\n * @param {Object} [additionalData] Additional data to be passed in `data` argument when firing `ViewConversionDispatcher`\n * events. See also {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:element element event}.\n * @returns {module:engine/model/node~Node|module:engine/model/documentfragment~DocumentFragment|null} The result of item conversion,\n * created and modified by callbacks attached to fired event, or `null` if the conversion result was incorrect.\n */\n\n/**\n * Starts conversion of all children of given item by firing appropriate events for all those children.\n *\n * @method #convertChildren\n * @fires module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:element\n * @fires module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:text\n * @fires module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:documentFragment\n * @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/element~Element}\n * input Item which children will be converted.\n * @param {module:engine/conversion/viewconsumable~ViewConsumable} consumable Values to consume.\n * @param {Object} [additionalData] Additional data to be passed in `data` argument when firing `ViewConversionDispatcher`\n * events. See also {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:element element event}.\n * @returns {module:engine/model/documentfragment~DocumentFragment} Model document fragment containing results of conversion\n * of all children of given item.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/viewconversiondispatcher.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport ModelDocumentFragment from '../model/documentfragment';\nimport ModelText from '../model/text';\nimport { normalizeNodes } from '../model/writer';\n\n/**\n * Contains {@link module:engine/view/view view} to {@link module:engine/model/model model} converters for\n * {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher}.\n *\n * @module engine/conversion/view-to-model-converters\n */\n\n/**\n * Function factory, creates a converter that converts {@link module:engine/view/documentfragment~DocumentFragment view document fragment}\n * or all children of {@link module:engine/view/element~Element} into\n * {@link module:engine/model/documentfragment~DocumentFragment model document fragment}.\n * This is the \"entry-point\" converter for 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~Node view nodes} are then 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~DocumentFragment model document fragment} and returned.\n *\n * @returns {Function} Universal converter for view {@link module:engine/view/documentfragment~DocumentFragment fragments} and\n * {@link module:engine/view/element~Element elements} that returns\n * {@link module:engine/model/documentfragment~DocumentFragment model fragment} with children of converted view item.\n */\nexport function convertToModelFragment() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\t// Second argument in `consumable.consume` is discarded for ViewDocumentFragment but is needed for ViewElement.\n\t\tif ( !data.output && consumable.consume( data.input, { name: true } ) ) {\n\t\t\tconst convertedChildren = conversionApi.convertChildren( data.input, consumable, data );\n\n\t\t\tdata.output = new ModelDocumentFragment( normalizeNodes( convertedChildren ) );\n\t\t}\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts {@link module:engine/view/text~Text} to {@link module:engine/model/text~Text}.\n *\n * @returns {Function} {@link module:engine/view/text~Text View text} converter.\n */\nexport function convertText() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst schemaQuery = {\n\t\t\tname: '$text',\n\t\t\tinside: data.context\n\t\t};\n\n\t\tif ( conversionApi.schema.check( schemaQuery ) ) {\n\t\t\tif ( consumable.consume( data.input ) ) {\n\t\t\t\tdata.output = new ModelText( data.input.data );\n\t\t\t}\n\t\t}\n\t};\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/view-to-model-converters.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/liveposition\n */\n\nimport Position from './position';\nimport Range from './range';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * `LivePosition` is a type of {@link module:engine/model/position~Position Position}\n * that updates itself as {@link module:engine/model/document~Document document}\n * is changed through operations. It may be used as a bookmark.\n *\n * **Note:** Contrary to {@link module:engine/model/position~Position}, `LivePosition` works only in roots that are\n * {@link module:engine/model/rootelement~RootElement}.\n * If {@link module:engine/model/documentfragment~DocumentFragment} is passed, error will be thrown.\n *\n * **Note:** Be very careful when dealing with `LivePosition`. Each `LivePosition` instance bind events that might\n * have to be unbound.\n * Use {@link module:engine/model/liveposition~LivePosition#detach} whenever you don't need `LivePosition` anymore.\n *\n * @extends module:engine/model/position~Position\n */\nexport default class LivePosition extends Position {\n\t/**\n\t * Creates a live position.\n\t *\n\t * @see module:engine/model/position~Position\n\t * @param {module:engine/model/rootelement~RootElement} root\n\t * @param {Array.<Number>} path\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness] Defaults to `'sticksToNext'`.\n\t * See {@link module:engine/model/liveposition~LivePosition#stickiness}.\n\t */\n\tconstructor( root, path, stickiness ) {\n\t\tsuper( root, path );\n\n\t\tif ( !this.root.is( 'rootElement' ) ) {\n\t\t\t/**\n\t\t\t * LivePosition's root has to be an instance of RootElement.\n\t\t\t *\n\t\t\t * @error liveposition-root-not-rootelement\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-liveposition-root-not-rootelement: LivePosition\\'s root has to be an instance of RootElement.'\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Flag representing `LivePosition` stickiness. `LivePosition` might be sticking to previous node or next node.\n\t\t * Whenever some nodes are inserted at the same position as `LivePosition`, `stickiness` is checked to decide if\n\t\t * LivePosition should be moved. Similar applies when a range of nodes is moved and one of it's boundary\n\t\t * position is same as `LivePosition`.\n\t\t *\n\t\t * Examples:\n\t\t *\n\t\t *\t\tInsert:\n\t\t *\t\tPosition is at | and we insert at the same position, marked as ^:\n\t\t *\t\t- | sticks to previous node: `<p>f|^oo</p>` => `<p>f|baroo</p>`\n\t\t *\t\t- | sticks to next node: `<p>f^|oo</p>` => `<p>fbar|oo</p>`\n\t\t *\n\t\t *\t\tMove:\n\t\t *\t\tPosition is at | and range [ ] is moved to position ^:\n\t\t *\t\t- | sticks to previous node: `<p>f|[oo]</p><p>b^ar</p>` => `<p>f|</p><p>booar</p>`\n\t\t *\t\t- | sticks to next node: `<p>f|[oo]</p><p>b^ar</p>` => `<p>f</p><p>b|ooar</p>`\n\t\t *\n\t\t * @member {module:engine/model/position~PositionStickiness} module:engine/model/liveposition~LivePosition#stickiness\n\t\t */\n\t\tthis.stickiness = stickiness || 'sticksToNext';\n\n\t\tbindWithDocument.call( this );\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by `LivePosition`. Use it whenever you don't need `LivePosition` 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\n\t/**\n\t * @static\n\t * @method module:engine/model/liveposition~LivePosition.createAfter\n\t * @see module:engine/model/position~Position.createAfter\n\t * @param {module:engine/model/node~Node} node\n\t * @returns {module:engine/model/liveposition~LivePosition}\n\t */\n\n\t/**\n\t * @static\n\t * @method module:engine/model/liveposition~LivePosition.createBefore\n\t * @see module:engine/model/position~Position.createBefore\n\t * @param {module:engine/model/node~Node} node\n\t * @returns {module:engine/model/liveposition~LivePosition}\n\t */\n\n\t/**\n\t * @static\n\t * @method module:engine/model/liveposition~LivePosition.createFromParentAndOffset\n\t * @see module:engine/model/position~Position.createFromParentAndOffset\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Number} offset\n\t * @returns {module:engine/model/liveposition~LivePosition}\n\t */\n\n\t/**\n\t * @static\n\t * @method module:engine/model/liveposition~LivePosition.createFromPosition\n\t * @see module:engine/model/position~Position.createFromPosition\n\t * @param {module:engine/model/position~Position} position\n\t * @returns {module:engine/model/liveposition~LivePosition}\n\t */\n\n\t/**\n\t * Fired when `LivePosition` instance is changed due to changes on {@link module:engine/model/document~Document}.\n\t *\n\t * @event module:engine/model/liveposition~LivePosition#change\n\t * @param {module:engine/model/position~Position} oldPosition Position equal to this live position before it got changed.\n\t */\n}\n\n/**\n * Binds this `LivePosition` to the {@link module:engine/model/document~Document document} that owns\n * this position's {@link module:engine/model/position~Position#root root}.\n *\n * @ignore\n * @private\n * @method module:engine/model/liveposition~LivePosition.bindWithDocument\n */\nfunction bindWithDocument() {\n\t// Operation types handled by LivePosition (these are operations that change model tree structure).\n\tconst supportedTypes = new Set( [ 'insert', 'move', 'remove', 'reinsert' ] );\n\n\tthis.listenTo(\n\t\tthis.root.document,\n\t\t'change',\n\t\t( event, type, changes ) => {\n\t\t\tif ( supportedTypes.has( type ) ) {\n\t\t\t\ttransform.call( this, type, changes.range, changes.sourcePosition );\n\t\t\t}\n\t\t},\n\t\t{ priority: 'high' }\n\t);\n}\n\n/**\n * Updates this position accordingly to the updates applied to the model. Bases on change events.\n *\n * @ignore\n * @private\n * @method transform\n * @param {String} type Type of changes applied to the Tree Model.\n * @param {module:engine/model/range~Range} range Range containing the result of applied change.\n * @param {module:engine/model/position~Position} [position] Additional position parameter provided by some change events.\n */\nfunction transform( type, range, position ) {\n\t/* eslint-disable no-case-declarations */\n\tconst howMany = range.end.offset - range.start.offset;\n\tlet transformed;\n\n\tswitch ( type ) {\n\t\tcase 'insert':\n\t\t\tconst insertBefore = this.stickiness == 'sticksToNext';\n\t\t\ttransformed = this._getTransformedByInsertion( range.start, howMany, insertBefore );\n\t\t\tbreak;\n\n\t\tcase 'move':\n\t\tcase 'remove':\n\t\tcase 'reinsert':\n\t\t\tconst originalRange = Range.createFromPositionAndShift( position, howMany );\n\n\t\t\tconst gotMoved = originalRange.containsPosition( this ) ||\n\t\t\t\t( originalRange.start.isEqual( this ) && this.stickiness == 'sticksToNext' ) ||\n\t\t\t\t( originalRange.end.isEqual( this ) && this.stickiness == 'sticksToPrevious' );\n\n\t\t\t// We can't use ._getTransformedByMove() because we have a different if-condition.\n\t\t\tif ( gotMoved ) {\n\t\t\t\ttransformed = this._getCombined( position, range.start );\n\t\t\t} else {\n\t\t\t\tconst insertBefore = this.stickiness == 'sticksToNext';\n\t\t\t\ttransformed = this._getTransformedByMove( position, range.start, howMany, insertBefore );\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\tif ( !this.isEqual( transformed ) ) {\n\t\tconst oldPosition = Position.createFromPosition( this );\n\n\t\tthis.path = transformed.path;\n\t\tthis.root = transformed.root;\n\n\t\tthis.fire( 'change', oldPosition );\n\t}\n\t/* eslint-enable no-case-declarations */\n}\n\nmix( LivePosition, EmitterMixin );\n\n/**\n * Enum representing how position is \"sticking\" with their neighbour nodes.\n * Possible values: `'sticksToNext'`, `'sticksToPrevious'`.\n *\n * @typedef {String} module:engine/model/position~PositionStickiness\n */\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/liveposition.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/controller/insertcontent\n */\n\nimport Position from '../model/position';\nimport LivePosition from '../model/liveposition';\nimport Element from '../model/element';\nimport Range from '../model/range';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\n/**\n * Inserts content into the editor (specified selection) as one would expect the paste\n * functionality to work.\n *\n * **Note:** Use {@link module:engine/controller/datacontroller~DataController#insertContent} instead of this function.\n * This function is only exposed to be reusable in algorithms\n * which change the {@link module:engine/controller/datacontroller~DataController#insertContent}\n * method's behavior.\n *\n * @param {module:engine/controller/datacontroller~DataController} dataController The data controller in context of which the insertion\n * should be performed.\n * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.\n * @param {module:engine/model/selection~Selection} selection Selection into which the content should be inserted.\n * @param {module:engine/model/batch~Batch} [batch] Batch to which deltas will be added. If not specified, then\n * changes will be added to a new batch.\n */\nexport default function insertContent( dataController, content, selection, batch ) {\n\tif ( !batch ) {\n\t\tbatch = dataController.model.batch();\n\t}\n\n\tif ( !selection.isCollapsed ) {\n\t\tdataController.deleteContent( selection, batch );\n\t}\n\n\tconst insertion = new Insertion( dataController, batch, selection.anchor );\n\n\tlet nodesToInsert;\n\n\tif ( content.is( 'documentFragment' ) ) {\n\t\tnodesToInsert = content.getChildren();\n\t} else {\n\t\tnodesToInsert = [ content ];\n\t}\n\n\tinsertion.handleNodes( nodesToInsert, {\n\t\t// The set of children being inserted is the only set in this context\n\t\t// so it's the first and last (it's a hack ;)).\n\t\tisFirst: true,\n\t\tisLast: true\n\t} );\n\n\tconst newRange = insertion.getSelectionRange();\n\n\t/* istanbul ignore else */\n\tif ( newRange ) {\n\t\tselection.setRanges( [ newRange ] );\n\t} else {\n\t\t// We are not testing else because it's a safe check for unpredictable edge cases:\n\t\t// an insertion without proper range to select.\n\n\t\t/**\n\t\t * Cannot determine a proper selection range after insertion.\n\t\t *\n\t\t * @warning insertcontent-no-range\n\t\t */\n\t\tlog.warn( 'insertcontent-no-range: Cannot determine a proper selection range after insertion.' );\n\t}\n}\n\n/**\n * Utility class for performing content insertion.\n *\n * @private\n */\nclass Insertion {\n\tconstructor( dataController, batch, position ) {\n\t\t/**\n\t\t * The data controller in context of which the insertion should be performed.\n\t\t *\n\t\t * @member {module:engine/controller/datacontroller~DataController} #dataController\n\t\t */\n\t\tthis.dataController = dataController;\n\n\t\t/**\n\t\t * Batch to which deltas will be added.\n\t\t *\n\t\t * @member {module:engine/controller/batch~Batch} #batch\n\t\t */\n\t\tthis.batch = batch;\n\n\t\t/**\n\t\t * The position at which (or near which) the next node will be inserted.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} #position\n\t\t */\n\t\tthis.position = position;\n\n\t\t/**\n\t\t * Elements with which the inserted elements can be merged.\n\t\t *\n\t\t *\t\t<p>x^</p><p>y</p> + <p>z</p> (can merge to <p>x</p>)\n\t\t *\t\t<p>x</p><p>^y</p> + <p>z</p> (can merge to <p>y</p>)\n\t\t *\t\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\t\t\t\tso both its pieces will be added to this set)\n\t\t *\n\t\t *\n\t\t * @member {Set} #canMergeWith\n\t\t */\n\t\tthis.canMergeWith = new Set( [ this.position.parent ] );\n\n\t\t/**\n\t\t * Schema of the model.\n\t\t *\n\t\t * @member {module:engine/model/schema~Schema} #schema\n\t\t */\n\t\tthis.schema = dataController.model.schema;\n\t}\n\n\t/**\n\t * Handles insertion of a set of nodes.\n\t *\n\t * @param {Iterable.<module:engine/model/node~Node>} nodes Nodes to insert.\n\t * @param {Object} parentContext Context in which parent of these nodes was supposed to be inserted.\n\t * If the parent context is passed it means that the parent element was stripped (was not allowed).\n\t */\n\thandleNodes( nodes, parentContext ) {\n\t\tnodes = Array.from( nodes );\n\n\t\tfor ( let i = 0; i < nodes.length; i++ ) {\n\t\t\tconst node = nodes[ i ];\n\n\t\t\tthis._handleNode( node, {\n\t\t\t\tisFirst: i === 0 && parentContext.isFirst,\n\t\t\t\tisLast: ( i === ( nodes.length - 1 ) ) && parentContext.isLast\n\t\t\t} );\n\t\t}\n\t}\n\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\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetSelectionRange() {\n\t\tif ( this.nodeToSelect ) {\n\t\t\treturn Range.createOn( this.nodeToSelect );\n\t\t}\n\n\t\treturn this.dataController.model.getNearestSelectionRange( this.position );\n\t}\n\n\t/**\n\t * Handles insertion of a single node.\n\t *\n\t * @param {module:engine/model/node~Node} node\n\t * @param {Object} context\n\t * @param {Boolean} context.isFirst Whether the given node is the first one in the content to be inserted.\n\t * @param {Boolean} context.isLast Whether the given node is the last one in the content to be inserted.\n\t */\n\t_handleNode( node, context ) {\n\t\t// Let's handle object in a special way.\n\t\t// * They should never be merged with other elements.\n\t\t// * If they are not allowed in any of the selection ancestors, they could be either autoparagraphed or totally removed.\n\t\tif ( this._checkIsObject( node ) ) {\n\t\t\tthis._handleObject( node, context );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Try to find a place for the given node.\n\t\t// Split the position.parent's branch up to a point where the node can be inserted.\n\t\t// If it isn't allowed in the whole branch, then of course don't split anything.\n\t\tconst isAllowed = this._checkAndSplitToAllowedPosition( node, context );\n\n\t\tif ( !isAllowed ) {\n\t\t\tthis._handleDisallowedNode( node, context );\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis._insert( node );\n\n\t\t// After the node was inserted we may try to merge it with its siblings.\n\t\t// This should happen only if it was the first and/or last of the nodes (so only with boundary nodes)\n\t\t// and only if the selection was in those elements initially.\n\t\t//\n\t\t// E.g.:\n\t\t// <p>x^</p> + <p>y</p> => <p>x</p><p>y</p> => <p>xy[]</p>\n\t\t// and:\n\t\t// <p>x^y</p> + <p>z</p> => <p>x</p>^<p>y</p> + <p>z</p> => <p>x</p><p>y</p><p>z</p> => <p>xy[]z</p>\n\t\t// but:\n\t\t// <p>x</p><p>^</p><p>z</p> + <p>y</p> => <p>x</p><p>y</p><p>z</p> (no merging)\n\t\t// <p>x</p>[<img>]<p>z</p> + <p>y</p> => <p>x</p><p>y</p><p>z</p> (no merging, note: after running deletetContents\n\t\t//\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t it's exactly the same case as above)\n\t\tthis._mergeSiblingsOf( node, context );\n\t}\n\n\t/**\n\t * @param {module:engine/model/element~Element} node The object element.\n\t * @param {Object} context\n\t */\n\t_handleObject( node, context ) {\n\t\t// Try finding it a place in the tree.\n\t\tif ( this._checkAndSplitToAllowedPosition( node ) ) {\n\t\t\tthis._insert( node );\n\t\t}\n\t\t// Try autoparagraphing.\n\t\telse {\n\t\t\tthis._tryAutoparagraphing( node, context );\n\t\t}\n\t}\n\n\t/**\n\t * @param {module:engine/model/node~Node} node The disallowed node which needs to be handled.\n\t * @param {Object} context\n\t */\n\t_handleDisallowedNode( node, context ) {\n\t\t// If the node is an element, try inserting its children (strip the parent).\n\t\tif ( node.is( 'element' ) ) {\n\t\t\tthis.handleNodes( node.getChildren(), context );\n\t\t}\n\t\t// If the node is a text and bare text is allowed in current position it means that the node\n\t\t// contains disallowed attributes and we have to remove them.\n\t\telse if ( this.schema.check( { name: '$text', inside: this.position } ) ) {\n\t\t\tthis.schema.removeDisallowedAttributes( [ node ], this.position );\n\t\t\tthis._handleNode( node, context );\n\t\t}\n\t\t// If text is not allowed, try autoparagraphing.\n\t\telse {\n\t\t\tthis._tryAutoparagraphing( node, context );\n\t\t}\n\t}\n\n\t/**\n\t * @param {module:engine/model/node~Node} node The node to insert.\n\t */\n\t_insert( node ) {\n\t\t/* istanbul ignore if */\n\t\tif ( !this._checkIsAllowed( node, this.position ) ) {\n\t\t\t// Algorithm's correctness check. We should never end up here but it's good to know that we did.\n\t\t\t// Note that it would often be a silent issue if we insert node in a place where it's not allowed.\n\t\t\tlog.error(\n\t\t\t\t'insertcontent-wrong-position: The node cannot be inserted on the given position.',\n\t\t\t\t{ node, position: this.position }\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst livePos = LivePosition.createFromPosition( this.position );\n\n\t\tthis.batch.insert( this.position, node );\n\n\t\tthis.position = Position.createFromPosition( livePos );\n\t\tlivePos.detach();\n\n\t\t// The last inserted object should be selected because we can't put a collapsed selection after it.\n\t\tif ( this._checkIsObject( node ) && !this.schema.check( { name: '$text', inside: this.position } ) ) {\n\t\t\tthis.nodeToSelect = node;\n\t\t} else {\n\t\t\tthis.nodeToSelect = null;\n\t\t}\n\t}\n\n\t/**\n\t * @param {module:engine/model/node~Node} node The node which could potentially be merged.\n\t * @param {Object} context\n\t */\n\t_mergeSiblingsOf( node, context ) {\n\t\tif ( !( node instanceof Element ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mergeLeft = context.isFirst && ( node.previousSibling instanceof Element ) && this.canMergeWith.has( node.previousSibling );\n\t\tconst mergeRight = context.isLast && ( node.nextSibling instanceof Element ) && this.canMergeWith.has( node.nextSibling );\n\t\tconst mergePosLeft = LivePosition.createBefore( node );\n\t\tconst mergePosRight = LivePosition.createAfter( node );\n\n\t\tif ( mergeLeft ) {\n\t\t\tconst position = LivePosition.createFromPosition( this.position );\n\n\t\t\tthis.batch.merge( mergePosLeft );\n\n\t\t\t// We need to check and strip disallowed attributes in all nested nodes because after merge\n\t\t\t// some attributes could end up in a path where are disallowed.\n\t\t\tconst parent = position.nodeBefore;\n\t\t\tthis.schema.removeDisallowedAttributes( parent.getChildren(), Position.createAt( parent ), this.batch );\n\n\t\t\tthis.position = Position.createFromPosition( position );\n\t\t\tposition.detach();\n\t\t}\n\n\t\tif ( mergeRight ) {\n\t\t\t/* istanbul ignore if */\n\t\t\tif ( !this.position.isEqual( mergePosRight ) ) {\n\t\t\t\t// Algorithm's correctness check. We should never end up here but it's good to know that we did.\n\t\t\t\t// At this point the insertion position should be after the node we'll merge. If it isn't,\n\t\t\t\t// it should need to be secured as in the left merge case.\n\t\t\t\tlog.error( 'insertcontent-wrong-position-on-merge: The insertion position should equal the merge position' );\n\t\t\t}\n\n\t\t\t// Move the position to the previous node, so it isn't moved to the graveyard on merge.\n\t\t\t// <p>x</p>[]<p>y</p> => <p>x[]</p><p>y</p>\n\t\t\tthis.position = Position.createAt( mergePosRight.nodeBefore, 'end' );\n\n\t\t\t// OK: <p>xx[]</p> + <p>yy</p> => <p>xx[]yy</p> (when sticks to previous)\n\t\t\t// NOK: <p>xx[]</p> + <p>yy</p> => <p>xxyy[]</p> (when sticks to next)\n\t\t\tconst position = new LivePosition( this.position.root, this.position.path, 'sticksToPrevious' );\n\n\t\t\tthis.batch.merge( mergePosRight );\n\n\t\t\t// We need to check and strip disallowed attributes in all nested nodes because after merge\n\t\t\t// some attributes could end up in a place where are disallowed.\n\t\t\tthis.schema.removeDisallowedAttributes( position.parent.getChildren(), position, this.batch );\n\n\t\t\tthis.position = Position.createFromPosition( position );\n\t\t\tposition.detach();\n\t\t}\n\n\t\tmergePosLeft.detach();\n\t\tmergePosRight.detach();\n\n\t\t// When there was no merge we need to check and strip disallowed attributes in all nested nodes of\n\t\t// just inserted node because some attributes could end up in a place where are disallowed.\n\t\tif ( !mergeLeft && !mergeRight ) {\n\t\t\tthis.schema.removeDisallowedAttributes( node.getChildren(), Position.createAt( node ), this.batch );\n\t\t}\n\t}\n\n\t/**\n\t * Tries wrapping the node in a new paragraph and inserting it this way.\n\t *\n\t * @param {module:engine/model/node~Node} node The node which needs to be autoparagraphed.\n\t * @param {Object} context\n\t */\n\t_tryAutoparagraphing( node, context ) {\n\t\tconst paragraph = new Element( 'paragraph' );\n\n\t\t// Do not autoparagraph if the paragraph won't be allowed there,\n\t\t// cause that would lead to an infinite loop. The paragraph would be rejected in\n\t\t// the next _handleNode() call and we'd be here again.\n\t\tif ( this._getAllowedIn( paragraph, this.position.parent ) ) {\n\t\t\t// When node is a text and is disallowed by schema it means that contains disallowed attributes\n\t\t\t// and we need to remove them.\n\t\t\tif ( node.is( 'text' ) && !this._checkIsAllowed( node, [ paragraph ] ) ) {\n\t\t\t\tthis.schema.removeDisallowedAttributes( [ node ], [ paragraph ] );\n\t\t\t}\n\n\t\t\tif ( this._checkIsAllowed( node, [ paragraph ] ) ) {\n\t\t\t\tparagraph.appendChildren( node );\n\t\t\t\tthis._handleNode( paragraph, context );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @param {module:engine/model/node~Node} node\n\t * @returns {Boolean} 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( node, this.position.parent );\n\n\t\tif ( !allowedIn ) {\n\t\t\treturn false;\n\t\t}\n\n\t\twhile ( allowedIn != this.position.parent ) {\n\t\t\t// If a parent which we'd need to leave is a limit element, break.\n\t\t\tif ( this.schema.limits.has( this.position.parent.name ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( this.position.isAtStart ) {\n\t\t\t\tconst parent = this.position.parent;\n\t\t\t\tthis.position = Position.createBefore( parent );\n\n\t\t\t\t// Special case parent is empty (<p>^</p>) so isAtStart == isAtEnd == true.\n\t\t\t\t// We can remove the element after moving selection out of it.\n\t\t\t\tif ( parent.isEmpty ) {\n\t\t\t\t\tthis.batch.remove( parent );\n\t\t\t\t}\n\t\t\t} else if ( this.position.isAtEnd ) {\n\t\t\t\tthis.position = Position.createAfter( this.position.parent );\n\t\t\t} else {\n\t\t\t\tconst tempPos = Position.createAfter( this.position.parent );\n\n\t\t\t\tthis.batch.split( this.position );\n\n\t\t\t\tthis.position = tempPos;\n\n\t\t\t\tthis.canMergeWith.add( this.position.nodeAfter );\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\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 * @param {module:engine/model/node~Node} node The node to check.\n\t * @param {module:engine/model/element~Element} element The element in which the node's correctness should be checked.\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\t_getAllowedIn( node, element ) {\n\t\tif ( this._checkIsAllowed( node, [ element ] ) ) {\n\t\t\treturn element;\n\t\t}\n\n\t\tif ( element.parent ) {\n\t\t\treturn this._getAllowedIn( node, element.parent );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Check whether the given node is allowed in the specified schema path.\n\t *\n\t * @param {module:engine/model/node~Node} node\n\t * @param {module:engine/model/schema~SchemaPath} path\n\t */\n\t_checkIsAllowed( node, path ) {\n\t\treturn this.schema.check( {\n\t\t\tname: getNodeSchemaName( node ),\n\t\t\tattributes: Array.from( node.getAttributeKeys() ),\n\t\t\tinside: path\n\t\t} );\n\t}\n\n\t/**\n\t * Checks whether according to the schema this is an object type element.\n\t *\n\t * @param {module:engine/model/node~Node} node The node to check.\n\t */\n\t_checkIsObject( node ) {\n\t\treturn this.schema.objects.has( getNodeSchemaName( node ) );\n\t}\n}\n\n// Gets a name under which we should check this node in the schema.\n//\n// @param {module:engine/model/node~Node} node The node.\n// @returns {String} Node name.\nfunction getNodeSchemaName( node ) {\n\treturn node.is( 'text' ) ? '$text' : node.name;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/controller/insertcontent.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/controller/deletecontent\n */\n\nimport LivePosition from '../model/liveposition';\nimport Position from '../model/position';\nimport Range from '../model/range';\nimport Element from '../model/element';\n\n/**\n * Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n *\n * @param {module:engine/model/selection~Selection} selection Selection of which the content should be deleted.\n * @param {module:engine/model/batch~Batch} batch Batch to which the deltas will be added.\n * @param {Object} [options]\n * @param {Boolean} [options.leaveUnmerged=false] 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~Schema#objects object} and {@link module:engine/model/schema~Schema#limits limit}\n * elements will not be merged.\n *\n * @param {Boolean} [options.doNotResetEntireContent=false] 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 */\nexport default function deleteContent( selection, batch, options = {} ) {\n\tif ( selection.isCollapsed ) {\n\t\treturn;\n\t}\n\n\tconst schema = batch.document.schema;\n\n\t// 1. Replace the entire content with paragraph.\n\t// See: https://github.com/ckeditor/ckeditor5-engine/issues/1012#issuecomment-315017594.\n\tif ( !options.doNotResetEntireContent && shouldEntireContentBeReplacedWithParagraph( schema, selection ) ) {\n\t\treplaceEntireContentWithParagraph( batch, selection );\n\n\t\treturn;\n\t}\n\n\tconst selRange = selection.getFirstRange();\n\tconst startPos = selRange.start;\n\tconst endPos = LivePosition.createFromPosition( selRange.end );\n\n\t// 2. Remove the content if there is any.\n\tif ( !selRange.start.isTouching( selRange.end ) ) {\n\t\tbatch.remove( selRange );\n\t}\n\n\t// 3. Merge elements in the right branch to the elements in the left branch.\n\t// The only reasonable (in terms of data and selection correctness) case in which we need to do that is:\n\t//\n\t// <heading type=1>Fo[</heading><paragraph>]ar</paragraph> => <heading type=1>Fo^ar</heading>\n\t//\n\t// However, the algorithm supports also merging deeper structures (up to the depth of the shallower branch),\n\t// as it's hard to imagine what should actually be the default behavior. Usually, specific features will\n\t// want to override that behavior anyway.\n\tif ( !options.leaveUnmerged ) {\n\t\tmergeBranches( batch, startPos, endPos );\n\n\t\t// We need to check and strip disallowed attributes in all nested nodes because after merge\n\t\t// some attributes could end up in a path where are disallowed.\n\t\t//\n\t\t// e.g. bold is disallowed for <H1>\n\t\t// <h1>Fo{o</h1><p>b}a<b>r</b><p> -> <h1>Fo{}a<b>r</b><h1> -> <h1>Fo{}ar<h1>.\n\t\tschema.removeDisallowedAttributes( startPos.parent.getChildren(), startPos, batch );\n\t}\n\n\tselection.setCollapsedAt( startPos );\n\n\t// 4. Autoparagraphing.\n\t// Check if a text is allowed in the new container. If not, try to create a new paragraph (if it's allowed here).\n\tif ( shouldAutoparagraph( schema, startPos ) ) {\n\t\tinsertParagraph( batch, startPos, selection );\n\t}\n\n\tendPos.detach();\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.\nfunction mergeBranches( batch, startPos, endPos ) {\n\tconst startParent = startPos.parent;\n\tconst endParent = endPos.parent;\n\n\t// If both positions ended up in the same parent, then there's nothing more to merge:\n\t// <$root><p>x[]</p><p>{}y</p></$root> => <$root><p>xy</p>[]{}</$root>\n\tif ( startParent == endParent ) {\n\t\treturn;\n\t}\n\n\t// If one of the positions is a root, then there's nothing more to merge (at least in the current state of implementation).\n\t// Theoretically in this case we could unwrap the <p>: <$root>x[]<p>{}y</p></$root>, but we don't need to support it yet\n\t// so let's just abort.\n\tif ( !startParent.parent || !endParent.parent ) {\n\t\treturn;\n\t}\n\n\t// Check if operations we'll need to do won't need to cross object or limit boundaries.\n\t// E.g., we can't merge endParent into startParent in this case:\n\t// <limit><startParent>x[]</startParent></limit><endParent>{}</endParent>\n\tif ( !checkCanBeMerged( startPos, endPos ) ) {\n\t\treturn;\n\t}\n\n\t// Remember next positions to merge. For example:\n\t// <a><b>x[]</b></a><c><d>{}y</d></c>\n\t// will become:\n\t// <a><b>xy</b>[]</a><c>{}</c>\n\tstartPos = Position.createAfter( startParent );\n\tendPos = Position.createBefore( endParent );\n\n\tif ( !endPos.isEqual( startPos ) ) {\n\t\t// In this case, before we merge, we need to move `endParent` to the `startPos`:\n\t\t// <a><b>x[]</b></a><c><d>{}y</d></c>\n\t\t// becomes:\n\t\t// <a><b>x</b>[]<d>y</d></a><c>{}</c>\n\t\tbatch.move( endParent, startPos );\n\t}\n\n\t// Merge two siblings:\n\t// <a>x</a>[]<b>y</b> -> <a>xy</a> (the usual case)\n\t// <a><b>x</b>[]<d>y</d></a><c></c> -> <a><b>xy</b>[]</a><c></c> (this is the \"move parent\" case shown above)\n\tbatch.merge( startPos );\n\n\t// Remove empty end ancestors:\n\t// <a>fo[o</a><b><a><c>bar]</c></a></b>\n\t// becomes:\n\t// <a>fo[]</a><b><a>{}</a></b>\n\t// So we can remove <a> and <b>.\n\twhile ( endPos.parent.isEmpty ) {\n\t\tconst parentToRemove = endPos.parent;\n\n\t\tendPos = Position.createBefore( parentToRemove );\n\n\t\tbatch.remove( parentToRemove );\n\t}\n\n\t// Continue merging next level.\n\tmergeBranches( batch, startPos, endPos );\n}\n\nfunction shouldAutoparagraph( schema, position ) {\n\tconst isTextAllowed = schema.check( { name: '$text', inside: position } );\n\tconst isParagraphAllowed = schema.check( { name: 'paragraph', inside: position } );\n\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.\nfunction checkCanBeMerged( leftPos, rightPos ) {\n\tconst schema = leftPos.root.document.schema;\n\tconst rangeToCheck = new Range( leftPos, rightPos );\n\n\tfor ( const value of rangeToCheck.getWalker() ) {\n\t\tif ( schema.objects.has( value.item.name ) || schema.limits.has( value.item.name ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction insertParagraph( batch, position, selection ) {\n\tconst paragraph = new Element( 'paragraph' );\n\tbatch.insert( position, paragraph );\n\n\tselection.setCollapsedAt( paragraph );\n}\n\nfunction replaceEntireContentWithParagraph( batch, selection ) {\n\tconst limitElement = batch.document.schema.getLimitElement( selection );\n\n\tbatch.remove( Range.createIn( limitElement ) );\n\tinsertParagraph( batch, Position.createAt( limitElement ), 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.\nfunction shouldEntireContentBeReplacedWithParagraph( schema, selection ) {\n\tconst limitElement = schema.getLimitElement( selection );\n\n\tif ( !selection.containsEntireContent( limitElement ) ) {\n\t\treturn false;\n\t}\n\n\tconst range = selection.getFirstRange();\n\n\tif ( range.start.parent == range.end.parent ) {\n\t\treturn false;\n\t}\n\n\treturn schema.check( { name: 'paragraph', inside: limitElement.name } );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/controller/deletecontent.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * Set of utils to handle unicode characters.\n *\n * @module utils/unicode\n */\n\n/**\n * Checks whether given `character` is a combining mark.\n *\n * @param {String} character Character to check.\n * @returns {Boolean}\n */\nexport function isCombiningMark( character ) {\n\treturn !!character && character.length == 1 && /[\\u0300-\\u036f\\u1ab0-\\u1aff\\u1dc0-\\u1dff\\u20d0-\\u20ff\\ufe20-\\ufe2f]/.test( character );\n}\n\n/**\n * Checks whether given `character` is a high half of surrogate pair.\n *\n * Using UTF-16 terminology, a surrogate pair denotes UTF-16 character using two UTF-8 characters. The surrogate pair\n * consist of high surrogate pair character followed by low surrogate pair character.\n *\n * @param {String} character Character to check.\n * @returns {Boolean}\n */\nexport function isHighSurrogateHalf( character ) {\n\treturn !!character && character.length == 1 && /[\\ud800-\\udbff]/.test( character );\n}\n\n/**\n * Checks whether given `character` is a low half of surrogate pair.\n *\n * Using UTF-16 terminology, a surrogate pair denotes UTF-16 character using two UTF-8 characters. The surrogate pair\n * consist of high surrogate pair character followed by low surrogate pair character.\n *\n * @param {String} character Character to check.\n * @returns {Boolean}\n */\nexport function isLowSurrogateHalf( character ) {\n\treturn !!character && character.length == 1 && /[\\udc00-\\udfff]/.test( character );\n}\n\n/**\n * Checks whether given offset in a string is inside a surrogate pair (between two surrogate halves).\n *\n * @param {String} string String to check.\n * @param {Number} offset Offset to check.\n * @returns {Boolean}\n */\nexport function isInsideSurrogatePair( string, offset ) {\n\treturn isHighSurrogateHalf( string.charAt( offset - 1 ) ) && isLowSurrogateHalf( string.charAt( offset ) );\n}\n\n/**\n * Checks whether given offset in a string is between base character and combining mark or between two combining marks.\n *\n * @param {String} string String to check.\n * @param {Number} offset Offset to check.\n * @returns {Boolean}\n */\nexport function isInsideCombinedSymbol( string, offset ) {\n\treturn isCombiningMark( string.charAt( offset ) );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/unicode.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/controller/modifyselection\n */\n\nimport Position from '../model/position';\nimport TreeWalker from '../model/treewalker';\nimport Range from '../model/range';\nimport { isInsideSurrogatePair, isInsideCombinedSymbol } from '@ckeditor/ckeditor5-utils/src/unicode';\n\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 *\n * **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n *\n * @param {module:engine/controller/datacontroller~DataController} dataController The data controller in context of which\n * the selection modification should be performed.\n * @param {module:engine/model/selection~Selection} selection The selection to modify.\n * @param {Object} [options]\n * @param {'forward'|'backward'} [options.direction='forward'] The direction in which the selection should be modified.\n * @param {'character'|'codePoint'} [options.unit='character'] The unit by which selection should be modified.\n */\nexport default function modifySelection( dataController, selection, options = {} ) {\n\tconst schema = dataController.model.schema;\n\tconst isForward = options.direction != 'backward';\n\tconst unit = options.unit ? options.unit : 'character';\n\n\tconst focus = selection.focus;\n\tconst walker = new TreeWalker( {\n\t\tboundaries: getSearchRange( focus, isForward ),\n\t\tsingleCharacters: true,\n\t\tdirection: isForward ? 'forward' : 'backward'\n\t} );\n\n\tconst data = { walker, schema, isForward, unit };\n\n\tlet next;\n\n\twhile ( ( next = walker.next() ) ) {\n\t\tif ( next.done ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = tryExtendingTo( data, next.value );\n\n\t\tif ( position ) {\n\t\t\tselection.moveFocusTo( position );\n\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).\nfunction tryExtendingTo( data, value ) {\n\t// If found text, we can certainly put the focus in it. Let's just find a correct position\n\t// based on the unit.\n\tif ( value.type == 'text' ) {\n\t\treturn getCorrectPosition( data.walker, data.unit );\n\t}\n\n\t// Entering an element.\n\tif ( value.type == ( data.isForward ? 'elementStart' : 'elementEnd' ) ) {\n\t\t// If it's an object, we can select it now.\n\t\tif ( data.schema.objects.has( value.item.name ) ) {\n\t\t\treturn Position.createAt( value.item, data.isForward ? 'after' : 'before' );\n\t\t}\n\n\t\t// If text allowed on this position, extend to this place.\n\t\tif ( data.schema.check( { name: '$text', inside: value.nextPosition } ) ) {\n\t\t\treturn value.nextPosition;\n\t\t}\n\t}\n\t// Leaving an element.\n\telse {\n\t\t// If leaving a limit element, stop.\n\t\tif ( data.schema.limits.has( value.item.name ) ) {\n\t\t\t// NOTE: Fast-forward the walker until the end.\n\t\t\tdata.walker.skip( () => true );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If text allowed on this position, extend to this place.\n\t\tif ( data.schema.check( { name: '$text', inside: value.nextPosition } ) ) {\n\t\t\treturn value.nextPosition;\n\t\t}\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.\nfunction getCorrectPosition( walker, unit ) {\n\tconst textNode = walker.position.textNode;\n\n\tif ( textNode ) {\n\t\tconst data = textNode.data;\n\t\tlet offset = walker.position.offset - textNode.startOffset;\n\n\t\twhile ( isInsideSurrogatePair( data, offset ) || ( unit == 'character' && isInsideCombinedSymbol( data, offset ) ) ) {\n\t\t\twalker.next();\n\n\t\t\toffset = walker.position.offset - textNode.startOffset;\n\t\t}\n\t}\n\n\treturn walker.position;\n}\n\nfunction getSearchRange( start, isForward ) {\n\tconst root = start.root;\n\tconst searchEnd = Position.createAt( root, isForward ? 'end' : 0 );\n\n\tif ( isForward ) {\n\t\treturn new Range( start, searchEnd );\n\t} else {\n\t\treturn new Range( searchEnd, start );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/controller/modifyselection.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/controller/getselectedcontent\n */\n\nimport DocumentFragment from '../model/documentfragment';\nimport Range from '../model/range';\nimport Position from '../model/position';\nimport Text from '../model/text';\nimport { remove } from '../model/writer';\n\n/**\n * Gets a clone of the selected content.\n *\n * For example, for the following selection:\n *\n *\t\t<p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n *\n * It will return a document fragment with such a content:\n *\n *\t\t<quote><h>st</h></quote><p>se</p>\n *\n * @param {module:engine/model/selection~Selection} selection The selection of which content will be returned.\n * @returns {module:engine/model/documentfragment~DocumentFragment}\n */\nexport default function getSelectedContent( selection ) {\n\tconst frag = new DocumentFragment();\n\tconst range = selection.getFirstRange();\n\n\tif ( !range || range.isCollapsed ) {\n\t\treturn frag;\n\t}\n\n\tconst root = range.start.root;\n\tconst commonPath = range.start.getCommonPath( range.end );\n\tconst commonParent = root.getNodeByPath( commonPath );\n\n\t// ## 1st step\n\t//\n\t// First, we'll clone a fragment represented by a minimal flat range\n\t// containing the original range to be cloned.\n\t// E.g. let's consider such a range:\n\t//\n\t// <p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n\t//\n\t// A minimal flat range containing this one is:\n\t//\n\t// <p>x</p>[<quote><p>y</p><h>first</h></quote><p>second</p>]<p>z</p>\n\t//\n\t// We can easily clone this structure, preserving e.g. the <quote> element.\n\tlet flatSubtreeRange;\n\n\tif ( range.start.parent == range.end.parent ) {\n\t\t// The original range is flat, so take it.\n\t\tflatSubtreeRange = range;\n\t} else {\n\t\tflatSubtreeRange = Range.createFromParentsAndOffsets(\n\t\t\tcommonParent, range.start.path[ commonPath.length ],\n\t\t\tcommonParent, range.end.path[ commonPath.length ] + 1\n\t\t);\n\t}\n\n\tconst howMany = flatSubtreeRange.end.offset - flatSubtreeRange.start.offset;\n\n\t// Clone the whole contents.\n\tfor ( const item of flatSubtreeRange.getItems( { shallow: true } ) ) {\n\t\tif ( item.is( 'textProxy' ) ) {\n\t\t\tfrag.appendChildren( new Text( item.data, item.getAttributes() ) );\n\t\t} else {\n\t\t\tfrag.appendChildren( item.clone( true ) );\n\t\t}\n\t}\n\n\t// ## 2nd step\n\t//\n\t// If the original range wasn't flat, then we need to remove the excess nodes from the both ends of the cloned fragment.\n\t//\n\t// For example, for the range shown in the 1st step comment, we need to remove these pieces:\n\t//\n\t// <quote>[<p>y</p>]<h>[fir]st</h></quote><p>se[cond]</p>\n\t//\n\t// So this will be the final copied content:\n\t//\n\t// <quote><h>st</h></quote><p>se</p>\n\t//\n\t// In order to do that, we remove content from these two ranges:\n\t//\n\t// [<quote><p>y</p><h>fir]st</h></quote><p>se[cond</p>]\n\tif ( flatSubtreeRange != range ) {\n\t\t// Find the position of the original range in the cloned fragment.\n\t\tconst newRange = range._getTransformedByMove( flatSubtreeRange.start, Position.createAt( frag, 0 ), howMany )[ 0 ];\n\n\t\tconst leftExcessRange = new Range( Position.createAt( frag ), newRange.start );\n\t\tconst rightExcessRange = new Range( newRange.end, Position.createAt( frag, 'end' ) );\n\n\t\tremoveRangeContent( rightExcessRange );\n\t\tremoveRangeContent( leftExcessRange );\n\t}\n\n\treturn frag;\n}\n\n// After https://github.com/ckeditor/ckeditor5-engine/issues/690 is fixed,\n// this function will, most likely, be able to rewritten using getMinimalFlatRanges().\nfunction removeRangeContent( range ) {\n\tconst parentsToCheck = [];\n\n\tArray.from( range.getItems( { direction: 'backward' } ) )\n\t\t// We should better store ranges because text proxies will lose integrity\n\t\t// with the text nodes when we'll start removing content.\n\t\t.map( item => Range.createOn( item ) )\n\t\t// Filter only these items which are fully contained in the passed range.\n\t\t//\n\t\t// E.g. for the following range: [<quote><p>y</p><h>fir]st</h>\n\t\t// the walker will return the entire <h> element, when only the \"fir\" item inside it is fully contained.\n\t\t.filter( itemRange => {\n\t\t\t// We should be able to use Range.containsRange, but https://github.com/ckeditor/ckeditor5-engine/issues/691.\n\t\t\tconst contained =\n\t\t\t\t( itemRange.start.isAfter( range.start ) || itemRange.start.isEqual( range.start ) ) &&\n\t\t\t\t( itemRange.end.isBefore( range.end ) || itemRange.end.isEqual( range.end ) );\n\n\t\t\treturn contained;\n\t\t} )\n\t\t.forEach( itemRange => {\n\t\t\tparentsToCheck.push( itemRange.start.parent );\n\n\t\t\tremove( itemRange );\n\t\t} );\n\n\t// Remove ancestors of the removed items if they turned to be empty now\n\t// (their whole content was contained in the range).\n\tparentsToCheck.forEach( parentToCheck => {\n\t\tlet parent = parentToCheck;\n\n\t\twhile ( parent.parent && parent.isEmpty ) {\n\t\t\tconst removeRange = Range.createOn( parent );\n\n\t\t\tparent = parent.parent;\n\n\t\t\tremove( removeRange );\n\t\t}\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/controller/getselectedcontent.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/controller/datacontroller\n */\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\n\nimport Mapper from '../conversion/mapper';\n\nimport ModelConversionDispatcher from '../conversion/modelconversiondispatcher';\nimport { insertText } from '../conversion/model-to-view-converters';\n\nimport ViewConversionDispatcher from '../conversion/viewconversiondispatcher';\nimport { convertText, convertToModelFragment } from '../conversion/view-to-model-converters';\n\nimport ViewDocumentFragment from '../view/documentfragment';\n\nimport ModelRange from '../model/range';\nimport ModelPosition from '../model/position';\nimport ModelElement from '../model/element';\n\nimport insertContent from './insertcontent';\nimport deleteContent from './deletecontent';\nimport modifySelection from './modifyselection';\nimport getSelectedContent from './getselectedcontent';\n\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 given:\n *\n * * {@link module:engine/dataprocessor/dataprocessor~DataProcessor data processor},\n * * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher model to view} and\n * * {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher view to model} converters.\n *\n * @mixes module:utils/emittermixin~ObservableMixin\n */\nexport default class DataController {\n\t/**\n\t * Creates data controller instance.\n\t *\n\t * @param {module:engine/model/document~Document} model Document model.\n\t * @param {module:engine/dataprocessor/dataprocessor~DataProcessor} [dataProcessor] Data processor which should used by the controller.\n\t */\n\tconstructor( model, dataProcessor ) {\n\t\t/**\n\t\t * Document model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/document~Document}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * Data processor used during the conversion.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/dataProcessor~DataProcessor}\n\t\t */\n\t\tthis.processor = dataProcessor;\n\n\t\t/**\n\t\t * Mapper used for the conversion. It has no permanent bindings, because they are created when getting data and\n\t\t * cleared directly after data are converted. However, the mapper is defined as class property, because\n\t\t * it needs to be passed to the `ModelConversionDispatcher` as a conversion API.\n\t\t *\n\t\t * @member {module:engine/conversion/mapper~Mapper}\n\t\t */\n\t\tthis.mapper = new Mapper();\n\n\t\t/**\n\t\t * Model to view conversion dispatcher used by the {@link #get get method}.\n\t\t * To attach model to view converter to the data pipeline you need to add lister to this property:\n\t\t *\n\t\t *\t\tdata.modelToView( 'insert:$element', customInsertConverter );\n\t\t *\n\t\t * Or use {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder}:\n\t\t *\n\t\t *\t\tbuildModelConverter().for( data.modelToView ).fromAttribute( 'bold' ).toElement( 'b' );\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}\n\t\t */\n\t\tthis.modelToView = new ModelConversionDispatcher( this.model, {\n\t\t\tmapper: this.mapper\n\t\t} );\n\t\tthis.modelToView.on( 'insert:$text', insertText(), { priority: 'lowest' } );\n\n\t\t/**\n\t\t * View to model conversion dispatcher used by the {@link #set set method}.\n\t\t * To attach view to model converter to the data pipeline you need to add lister to this property:\n\t\t *\n\t\t *\t\tdata.viewToModel( 'element', customElementConverter );\n\t\t *\n\t\t * Or use {@link module:engine/conversion/buildviewconverter~ViewConverterBuilder}:\n\t\t *\n\t\t *\t\tbuildViewConverter().for( data.viewToModel ).fromElement( 'b' ).toAttribute( 'bold', 'true' );\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher}\n\t\t */\n\t\tthis.viewToModel = new ViewConversionDispatcher( {\n\t\t\tschema: model.schema\n\t\t} );\n\n\t\t// Define default converters for text and elements.\n\t\t//\n\t\t// Note that if there is no default converter for the element it will be skipped, for instance `<b>foo</b>` will be\n\t\t// converted to nothing. We add `convertToModelFragment` as a last converter so it converts children of that\n\t\t// element to the document fragment so `<b>foo</b>` will be converted to `foo` if there is no converter for `<b>`.\n\t\tthis.viewToModel.on( 'text', convertText(), { priority: 'lowest' } );\n\t\tthis.viewToModel.on( 'element', convertToModelFragment(), { priority: 'lowest' } );\n\t\tthis.viewToModel.on( 'documentFragment', convertToModelFragment(), { priority: 'lowest' } );\n\n\t\t[ 'insertContent', 'deleteContent', 'modifySelection', 'getSelectedContent' ]\n\t\t\t.forEach( methodName => this.decorate( methodName ) );\n\t}\n\n\t/**\n\t * Returns model's data converted by the {@link #modelToView model to view converters} and\n\t * formatted by the {@link #processor data processor}.\n\t *\n\t * @param {String} [rootName='main'] Root name.\n\t * @returns {String} Output data.\n\t */\n\tget( rootName = 'main' ) {\n\t\t// Get model range.\n\t\treturn this.stringify( this.model.getRoot( rootName ) );\n\t}\n\n\t/**\n\t * Returns the content of the given {@link module:engine/model/element~Element model's element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the\n\t * {@link #modelToView model to view converters} and formatted by the\n\t * {@link #processor data processor}.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment\n\t * Element which content will be stringified.\n\t * @returns {String} Output data.\n\t */\n\tstringify( modelElementOrFragment ) {\n\t\t// model -> view\n\t\tconst viewDocumentFragment = this.toView( modelElementOrFragment );\n\n\t\t// view -> data\n\t\treturn this.processor.toData( viewDocumentFragment );\n\t}\n\n\t/**\n\t * Returns the content of the given {@link module:engine/model/element~Element model element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the\n\t * {@link #modelToView model to view converters} to a\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment\n\t * Element or document fragment which content will be converted.\n\t * @returns {module:engine/view/documentfragment~DocumentFragment} Output view DocumentFragment.\n\t */\n\ttoView( modelElementOrFragment ) {\n\t\tconst modelRange = ModelRange.createIn( modelElementOrFragment );\n\n\t\tconst viewDocumentFragment = new ViewDocumentFragment();\n\t\tthis.mapper.bindElements( modelElementOrFragment, viewDocumentFragment );\n\n\t\tthis.modelToView.convertInsertion( modelRange );\n\n\t\tthis.mapper.clearBindings();\n\n\t\treturn viewDocumentFragment;\n\t}\n\n\t/**\n\t * Sets input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #viewToModel view to model converters}.\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 * @param {String} data Input data.\n\t * @param {String} [rootName='main'] Root name.\n\t */\n\tset( data, rootName = 'main' ) {\n\t\t// Save to model.\n\t\tconst modelRoot = this.model.getRoot( rootName );\n\n\t\tthis.model.enqueueChanges( () => {\n\t\t\t// Clearing selection is a workaround for ticket #569 (LiveRange loses position after removing data from document).\n\t\t\t// After fixing it this code should be removed.\n\t\t\tthis.model.selection.removeAllRanges();\n\t\t\tthis.model.selection.clearAttributes();\n\n\t\t\t// Initial batch should be ignored by features like undo, etc.\n\t\t\tthis.model.batch( 'transparent' )\n\t\t\t\t.remove( ModelRange.createIn( modelRoot ) )\n\t\t\t\t.insert( ModelPosition.createAt( modelRoot, 0 ), this.parse( data ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Returns data parsed by the {@link #processor data processor} and then\n\t * converted by the {@link #viewToModel view to model converters}.\n\t *\n\t * @see #set\n\t * @param {String} data Data to parse.\n\t * @param {String} [context='$root'] Base context in which the view will be converted to the model. See:\n\t * {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#convert}.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Parsed data.\n\t */\n\tparse( data, context = '$root' ) {\n\t\t// data -> view\n\t\tconst viewDocumentFragment = this.processor.toView( data );\n\n\t\t// view -> model\n\t\treturn this.toModel( viewDocumentFragment, context );\n\t}\n\n\t/**\n\t * Returns wrapped by {module:engine/model/documentfragment~DocumentFragment} result of the given\n\t * {@link module:engine/view/element~Element view element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment} converted by the\n\t * {@link #viewToModel view to model converters}.\n\t *\n\t * When marker elements were converted during conversion process then will be set as DocumentFragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewElementOrFragment\n\t * Element or document fragment which content will be converted.\n\t * @param {String} [context='$root'] Base context in which the view will be converted to the model. See:\n\t * {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#convert}.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Output document fragment.\n\t */\n\ttoModel( viewElementOrFragment, context = '$root' ) {\n\t\treturn this.viewToModel.convert( viewElementOrFragment, { context: [ context ] } );\n\t}\n\n\t/**\n\t * Removes all event listeners set by the DataController.\n\t */\n\tdestroy() {}\n\n\t/**\n\t * See {@link module:engine/controller/insertcontent.insertContent}.\n\t *\n\t * @fires insertContent\n\t * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.\n\t * @param {module:engine/model/selection~Selection} selection Selection into which the content should be inserted.\n\t * @param {module:engine/model/batch~Batch} [batch] Batch to which deltas will be added. If not specified, then\n\t * changes will be added to a new batch.\n\t */\n\tinsertContent( content, selection, batch ) {\n\t\tinsertContent( this, content, selection, batch );\n\t}\n\n\t/**\n\t * See {@link module:engine/controller/deletecontent.deleteContent}.\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 {module:engine/model/selection~Selection} selection Selection of which the content should be deleted.\n\t * @param {module:engine/model/batch~Batch} batch Batch to which deltas will be added.\n\t * @param {Object} options See {@link module:engine/controller/deletecontent~deleteContent}'s options.\n\t */\n\tdeleteContent( selection, batch, options ) {\n\t\tdeleteContent( selection, batch, options );\n\t}\n\n\t/**\n\t * See {@link module:engine/controller/modifyselection.modifySelection}.\n\t *\n\t * @fires modifySelection\n\t * @param {module:engine/model/selection~Selection} selection The selection to modify.\n\t * @param {Object} options See {@link module:engine/controller/modifyselection~modifySelection}'s options.\n\t */\n\tmodifySelection( selection, options ) {\n\t\tmodifySelection( this, selection, options );\n\t}\n\n\t/**\n\t * See {@link module:engine/controller/getselectedcontent.getSelectedContent}.\n\t *\n\t * @fires module:engine/controller/datacontroller~DataController#getSelectedContent\n\t * @param {module:engine/model/selection~Selection} selection The selection of which content will be retrieved.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Document fragment holding the clone of the selected content.\n\t */\n\tgetSelectedContent( selection ) {\n\t\treturn getSelectedContent( selection );\n\t}\n\n\t/**\n\t * Checks whether given {@link module:engine/model/range~Range range} or {@link module:engine/model/element~Element element}\n\t * has any content.\n\t *\n\t * Content is any text node or element which is registered in {@link module:engine/model/schema~Schema schema}.\n\t *\n\t * @param {module:engine/model/range~Range|module:engine/model/element~Element} rangeOrElement Range or element to check.\n\t * @returns {Boolean}\n\t */\n\thasContent( rangeOrElement ) {\n\t\tif ( rangeOrElement instanceof ModelElement ) {\n\t\t\trangeOrElement = ModelRange.createIn( rangeOrElement );\n\t\t}\n\n\t\tif ( rangeOrElement.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const item of rangeOrElement.getItems() ) {\n\t\t\t// Remember, `TreeWalker` returns always `textProxy` nodes.\n\t\t\tif ( item.is( 'textProxy' ) || this.model.schema.objects.has( item.name ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\nmix( DataController, ObservableMixin );\n\n/**\n * Event fired when {@link #insertContent} method is called.\n *\n * The {@link #insertContent default action of that method} is implemented as a\n * listener to this event so it can be fully customized by the features.\n *\n * @event insertContent\n * @param {Array} args The arguments passed to the original method.\n */\n\n/**\n * Event fired when {@link #deleteContent} method is called.\n *\n * The {@link #deleteContent default action of that method} is implemented as a\n * listener to this event so it can be fully customized by the features.\n *\n * @event deleteContent\n * @param {Array} args The arguments passed to the original method.\n */\n\n/**\n * Event fired when {@link #modifySelection} method is called.\n *\n * The {@link #modifySelection default action of that method} is implemented as a\n * listener to this event so it can be fully customized by the features.\n *\n * @event modifySelection\n * @param {Array} args The arguments passed to the original method.\n */\n\n/**\n * Event fired when {@link #getSelectedContent} method is called.\n *\n * The {@link #getSelectedContent default action of that method} is implemented as a\n * listener to this event so it can be fully customized by the features.\n *\n * @event getSelectedContent\n * @param {Array} args The arguments passed to the original method.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/controller/datacontroller.js\n// module id = null\n// module chunks = ","import MapCache from './_MapCache';\nimport setCacheAdd from './_setCacheAdd';\nimport setCacheHas from './_setCacheHas';\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values ? values.length : 0;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nexport default SetCache;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_SetCache.js\n// module id = null\n// module chunks = ","import baseIsEqualDeep from './_baseIsEqualDeep';\nimport isObject from './isObject';\nimport isObjectLike from './isObjectLike';\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {boolean} [bitmask] The bitmask of comparison flags.\n * The bitmask may be composed of the following flags:\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, customizer, bitmask, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);\n}\n\nexport default baseIsEqual;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseIsEqual.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/batch\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * `Batch` instance groups document changes ({@link module:engine/model/delta/delta~Delta deltas}). All deltas grouped in a single `Batch`\n * can be reverted together, so you can think about `Batch` as of a single undo step. If you want to extend given undo step you\n * can call another method on the same `Batch` object. If you want to create a separate undo step you can create a new `Batch`.\n *\n * For example to create two separate undo steps you can call:\n *\n *\t\tdoc.batch().insert( firstPosition, 'foo' );\n *\t\tdoc.batch().insert( secondPosition, 'bar' );\n *\n * To create a single undo step:\n *\n *\t\tconst batch = doc.batch();\n *\t\tbatch.insert( firstPosition, 'foo' );\n *\t\tbatch.insert( secondPosition, 'bar' );\n *\n * Note that all document modification methods (insert, remove, split, etc.) are chainable so you can shorten code to:\n *\n *\t\tdoc.batch().insert( firstPosition, 'foo' ).insert( secondPosition, 'bar' );\n */\nexport default class Batch {\n\t/**\n\t * Creates `Batch` instance. Not recommended to use directly, use {@link module:engine/model/document~Document#batch} instead.\n\t *\n\t * @param {module:engine/model/document~Document} document Document which this Batch changes.\n\t * @param {'transparent'|'default'} [type='default'] Type of the batch.\n\t */\n\tconstructor( document, type = 'default' ) {\n\t\t/**\n\t\t * Document which this batch changes.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/document~Document} module:engine/model/batch~Batch#document\n\t\t */\n\t\tthis.document = document;\n\n\t\t/**\n\t\t * Array of deltas which compose this batch.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<module:engine/model/delta/delta~Delta>} module:engine/model/batch~Batch#deltas\n\t\t */\n\t\tthis.deltas = [];\n\n\t\t/**\n\t\t * Type of the batch.\n\t\t *\n\t\t * Can be one of the following values:\n\t\t * * `'default'` - all \"normal\" batches, most commonly used type.\n\t\t * * `'transparent'` - batch that should be ignored by other features, i.e. initial batch or collaborative editing changes.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'transparent'|'default'} module:engine/model/batch~Batch#type\n\t\t */\n\t\tthis.type = type;\n\t}\n\n\t/**\n\t * Returns this batch base version, which is equal to the base version of first delta in the batch.\n\t * If there are no deltas in the batch, it returns `null`.\n\t *\n\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget baseVersion() {\n\t\treturn this.deltas.length > 0 ? this.deltas[ 0 ].baseVersion : null;\n\t}\n\n\t/**\n\t * Adds delta to the batch instance. All modification methods (insert, remove, split, etc.) use this method\n\t * to add created deltas.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} delta Delta to add.\n\t * @return {module:engine/model/delta/delta~Delta} Added delta.\n\t */\n\taddDelta( delta ) {\n\t\tdelta.batch = this;\n\t\tthis.deltas.push( delta );\n\n\t\treturn delta;\n\t}\n\n\t/**\n\t * Gets an iterable collection of operations.\n\t *\n\t * @returns {Iterable.<module:engine/model/operation/operation~Operation>}\n\t */\n\t* getOperations() {\n\t\tfor ( const delta of this.deltas ) {\n\t\t\tyield* delta.operations;\n\t\t}\n\t}\n}\n\n/**\n * Function to register batch methods. To make code scalable `Batch` do not have modification\n * methods built in. They can be registered using this method.\n *\n * This method checks if there is no naming collision and throws `batch-register-taken` if the method name\n * is already taken.\n *\n * Besides that no magic happens here, the method is added to the `Batch` class prototype.\n *\n * For example:\n *\n *\t\tBatch.register( 'insert', function( position, nodes ) {\n *\t\t\t// You can use a class inheriting from `Delta` if that class should handle OT in a special way.\n *\t\t\tconst delta = new Delta();\n *\n *\t\t\t// Add delta to the Batch instance. It is important to add a delta to the batch before applying any operation.\n *\t\t\tthis.addDelta( delta );\n *\n *\t\t\t// Create operations which should be components of this delta.\n *\t\t\tconst operation = new InsertOperation( position, nodes, this.document.version );\n *\n *\t\t\t// Add operation to the delta. It is important to add operation before applying it.\n *\t\t\tdelta.addOperation( operation );\n *\n *\t\t\t// Remember to apply every operation, no magic, you need to do it manually.\n *\t\t\tthis.document.applyOperation( operation );\n *\n *\t\t\t// Make this method chainable.\n *\t\t\treturn this;\n *\t\t} );\n *\n * @method module:engine/model/batch~Batch.register\n * @param {String} name Method name.\n * @param {Function} creator Method body.\n */\nexport function register( name, creator ) {\n\tif ( Batch.prototype[ name ] ) {\n\t\t/**\n\t\t * This batch method name is already taken.\n\t\t *\n\t\t * @error batch-register-taken\n\t\t * @param {String} name\n\t\t */\n\t\tthrow new CKEditorError(\n\t\t\t'model-batch-register-taken: This batch method name is already taken.',\n\t\t\t{ name } );\n\t}\n\n\tBatch.prototype[ name ] = creator;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/batch.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/attributedelta\n */\n\nimport Delta from './delta';\nimport DeltaFactory from './deltafactory';\nimport { register } from '../batch';\nimport AttributeOperation from '../operation/attributeoperation';\nimport RootAttributeOperation from '../operation/rootattributeoperation';\nimport NoOperation from '../operation/nooperation';\nimport Position from '../position';\nimport Range from '../range';\n\n/**\n * To provide specific OT behavior and better collisions solving, methods to change attributes\n * ({@link module:engine/model/batch~Batch#setAttribute} and {@link module:engine/model/batch~Batch#removeAttribute})\n * use `AttributeDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class AttributeDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'attribute';\n\t}\n\n\t/**\n\t * The attribute key that is changed by the delta or `null` if the delta has no operations.\n\t *\n\t * @readonly\n\t * @type {String|null}\n\t */\n\tget key() {\n\t\treturn this.operations[ 0 ] ? this.operations[ 0 ].key : null;\n\t}\n\n\t/**\n\t * The attribute value that is set by the delta or `null` if the delta has no operations.\n\t *\n\t * @readonly\n\t * @type {*|null}\n\t */\n\tget value() {\n\t\treturn this.operations[ 0 ] ? this.operations[ 0 ].newValue : null;\n\t}\n\n\t/**\n\t * The range on which delta operates or `null` if the delta has no operations.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/range~Range|null}\n\t */\n\tget range() {\n\t\t// Check if it is cached.\n\t\tif ( this._range ) {\n\t\t\treturn this._range;\n\t\t}\n\n\t\tlet start = null;\n\t\tlet end = null;\n\n\t\tfor ( const operation of this.operations ) {\n\t\t\tif ( operation instanceof NoOperation ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( start === null || start.isAfter( operation.range.start ) ) {\n\t\t\t\tstart = operation.range.start;\n\t\t\t}\n\n\t\t\tif ( end === null || end.isBefore( operation.range.end ) ) {\n\t\t\t\tend = operation.range.end;\n\t\t\t}\n\t\t}\n\n\t\tif ( start && end ) {\n\t\t\tthis._range = new Range( start, end );\n\n\t\t\treturn this._range;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tget _reverseDeltaClass() {\n\t\treturn AttributeDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tdelete json._range;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.AttributeDelta';\n\t}\n}\n\n/**\n * To provide specific OT behavior and better collisions solving, methods to change attributes\n * ({@link module:engine/model/batch~Batch#setAttribute} and {@link module:engine/model/batch~Batch#removeAttribute})\n * use `RootAttributeDelta` class which inherits from the `Delta` class and may\n * overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport class RootAttributeDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.RootAttributeDelta';\n\t}\n}\n\n/**\n * Sets value of the attribute with given key on a {@link module:engine/model/item~Item model item}\n * or on a {@link module:engine/model/range~Range range}.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#setAttribute\n * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange\n * Model item or range on which the attribute will be set.\n * @param {String} key Attribute key.\n * @param {*} value Attribute new value.\n */\nregister( 'setAttribute', function( itemOrRange, key, value ) {\n\tattribute( this, key, value, itemOrRange );\n\n\treturn this;\n} );\n\n/**\n * Removes an attribute with given key from a {@link module:engine/model/item~Item model item}\n * or from a {@link module:engine/model/range~Range range}.\n *\n * @chainable\n * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange\n * Model item or range from which the attribute will be removed.\n * @method module:engine/model/batch~Batch#removeAttribute\n * @param {String} key Attribute key.\n */\nregister( 'removeAttribute', function( itemOrRange, key ) {\n\tattribute( this, key, null, itemOrRange );\n\n\treturn this;\n} );\n\nfunction attribute( batch, key, value, itemOrRange ) {\n\tif ( itemOrRange instanceof Range ) {\n\t\tchangeRange( batch, batch.document, key, value, itemOrRange );\n\t} else {\n\t\tchangeItem( batch, batch.document, key, value, itemOrRange );\n\t}\n}\n\nfunction changeItem( batch, doc, key, value, item ) {\n\tconst previousValue = item.getAttribute( key );\n\tlet range, operation;\n\n\tconst delta = item.is( 'rootElement' ) ? new RootAttributeDelta() : new AttributeDelta();\n\n\tif ( previousValue != value ) {\n\t\tbatch.addDelta( delta );\n\n\t\tif ( item.is( 'rootElement' ) ) {\n\t\t\t// If we change attributes of root element, we have to use `RootAttributeOperation`.\n\t\t\toperation = new RootAttributeOperation( item, key, previousValue, value, doc.version );\n\t\t} else {\n\t\t\tif ( item.is( 'element' ) ) {\n\t\t\t\t// If we change the attribute of the element, we do not want to change attributes of its children, so\n\t\t\t\t// the end of the range cannot be after the closing tag, it should be inside that element, before any of\n\t\t\t\t// it's children, so the range will contain only the opening tag.\n\t\t\t\trange = new Range( Position.createBefore( item ), Position.createFromParentAndOffset( item, 0 ) );\n\t\t\t} else {\n\t\t\t\t// If `item` is text proxy, we create a range from the beginning to the end of that text proxy, to change\n\t\t\t\t// all characters represented by it.\n\t\t\t\trange = new Range( Position.createBefore( item ), Position.createAfter( item ) );\n\t\t\t}\n\n\t\t\toperation = new AttributeOperation( range, key, previousValue, value, doc.version );\n\t\t}\n\n\t\tdelta.addOperation( operation );\n\t\tdoc.applyOperation( operation );\n\t}\n}\n\n// Because attribute operation needs to have the same attribute value on the whole range, this function splits the range\n// into smaller parts.\nfunction changeRange( batch, doc, attributeKey, attributeValue, range ) {\n\tconst delta = new AttributeDelta();\n\n\t// Position of the last split, the beginning of the new range.\n\tlet lastSplitPosition = range.start;\n\n\t// Currently position in the scanning range. Because we need value after the position, it is not a current\n\t// position of the iterator but the previous one (we need to iterate one more time to get the value after).\n\tlet position,\n\t\t// Value before the currently position.\n\t\tattributeValueBefore,\n\t\t// Value after the currently position.\n\t\tattributeValueAfter;\n\n\tfor ( const value of range ) {\n\t\tattributeValueAfter = value.item.getAttribute( attributeKey );\n\n\t\t// At the first run of the iterator the position in undefined. We also do not have a attributeValueBefore, but\n\t\t// because attributeValueAfter may be null, attributeValueBefore may be equal attributeValueAfter ( undefined == null ).\n\t\tif ( position && attributeValueBefore != attributeValueAfter ) {\n\t\t\t// if attributeValueBefore == attributeValue there is nothing to change, so we add operation only if these values are different.\n\t\t\tif ( attributeValueBefore != attributeValue ) {\n\t\t\t\taddOperation();\n\t\t\t}\n\n\t\t\tlastSplitPosition = position;\n\t\t}\n\n\t\tposition = value.nextPosition;\n\t\tattributeValueBefore = attributeValueAfter;\n\t}\n\n\t// Because position in the loop is not the iterator position (see let position comment), the last position in\n\t// the while loop will be last but one position in the range. We need to check the last position manually.\n\tif ( position instanceof Position && position != lastSplitPosition && attributeValueBefore != attributeValue ) {\n\t\taddOperation();\n\t}\n\n\tfunction addOperation() {\n\t\t// Add delta to the batch only if there is at least operation in the delta. Add delta only once.\n\t\tif ( delta.operations.length === 0 ) {\n\t\t\tbatch.addDelta( delta );\n\t\t}\n\n\t\tconst range = new Range( lastSplitPosition, position );\n\t\tconst operation = new AttributeOperation( range, attributeKey, attributeValueBefore, attributeValue, doc.version );\n\n\t\tdelta.addOperation( operation );\n\t\tdoc.applyOperation( operation );\n\t}\n}\n\nDeltaFactory.register( AttributeDelta );\nDeltaFactory.register( RootAttributeDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/attributedelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/movedelta\n */\n\nimport Delta from './delta';\nimport DeltaFactory from './deltafactory';\nimport { register } from '../batch';\nimport MoveOperation from '../operation/moveoperation';\nimport Position from '../position';\nimport Range from '../range';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#move} method\n * uses the `MoveDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class MoveDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'move';\n\t}\n\n\t/**\n\t * Offset size of moved range or `null` if there are no operations in the delta.\n\t *\n\t * @type {Number|null}\n\t */\n\tget howMany() {\n\t\treturn this._moveOperation ? this._moveOperation.howMany : null;\n\t}\n\n\t/**\n\t * {@link module:engine/model/delta/movedelta~MoveDelta#_moveOperation Move operation}\n\t * {@link module:engine/model/operation/moveoperation~MoveOperation#sourcePosition source position} or `null` if there are\n\t * no operations in the delta.\n\t *\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget sourcePosition() {\n\t\treturn this._moveOperation ? this._moveOperation.sourcePosition : null;\n\t}\n\n\t/**\n\t * {@link module:engine/model/delta/movedelta~MoveDelta#_moveOperation Move operation}\n\t * {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition target position} or `null` if there are\n\t * no operations in the delta.\n\t *\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget targetPosition() {\n\t\treturn this._moveOperation ? this._moveOperation.targetPosition : null;\n\t}\n\n\t/**\n\t * {@link module:engine/model/delta/movedelta~MoveDelta#_moveOperation Move operation} that is saved in this delta or `null`\n\t * if there are no operations in the delta.\n\t *\n\t * @protected\n\t * @type {module:engine/model/operation/moveoperation~MoveOperation|null}\n\t */\n\tget _moveOperation() {\n\t\treturn this.operations[ 0 ] || null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn MoveDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.MoveDelta';\n\t}\n}\n\nfunction addMoveOperation( batch, delta, sourcePosition, howMany, targetPosition ) {\n\tconst operation = new MoveOperation( sourcePosition, howMany, targetPosition, batch.document.version );\n\tdelta.addOperation( operation );\n\tbatch.document.applyOperation( operation );\n}\n\n/**\n * Moves given {@link module:engine/model/item~Item model item} or given range to target position.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#move\n * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange Model item or range of nodes to move.\n * @param {module:engine/model/position~Position} targetPosition Position where moved nodes will be inserted.\n */\nregister( 'move', function( itemOrRange, targetPosition ) {\n\tconst delta = new MoveDelta();\n\tthis.addDelta( delta );\n\n\tif ( itemOrRange instanceof Range ) {\n\t\tif ( !itemOrRange.isFlat ) {\n\t\t\t/**\n\t\t\t * Range to move is not flat.\n\t\t\t *\n\t\t\t * @error batch-move-range-not-flat\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'batch-move-range-not-flat: Range to move is not flat.' );\n\t\t}\n\n\t\taddMoveOperation( this, delta, itemOrRange.start, itemOrRange.end.offset - itemOrRange.start.offset, targetPosition );\n\t} else {\n\t\taddMoveOperation( this, delta, Position.createBefore( itemOrRange ), 1, targetPosition );\n\t}\n\n\treturn this;\n} );\n\nDeltaFactory.register( MoveDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/movedelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/removedelta\n */\n\nimport MoveDelta from './movedelta';\nimport { register } from '../batch';\nimport DeltaFactory from './deltafactory';\nimport RemoveOperation from '../operation/removeoperation';\nimport Position from '../position';\nimport Range from '../range';\n\n/**\n * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#remove} method\n * uses the `RemoveDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class RemoveDelta extends MoveDelta {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.RemoveDelta';\n\t}\n}\n\nfunction addRemoveDelta( batch, position, howMany ) {\n\tconst delta = new RemoveDelta();\n\tbatch.addDelta( delta );\n\n\tconst graveyard = batch.document.graveyard;\n\tconst gyPosition = new Position( graveyard, [ 0 ] );\n\n\tconst operation = new RemoveOperation( position, howMany, gyPosition, batch.document.version );\n\tdelta.addOperation( operation );\n\tbatch.document.applyOperation( operation );\n}\n\n/**\n * Removes given {@link module:engine/model/item~Item model item} or given range.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#remove\n * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange Model item or range to remove.\n */\nregister( 'remove', function( itemOrRange ) {\n\tif ( itemOrRange instanceof Range ) {\n\t\t// The array is reversed, so the ranges to remove are in correct order and do not have to be updated.\n\t\tconst ranges = itemOrRange.getMinimalFlatRanges().reverse();\n\n\t\tfor ( const flat of ranges ) {\n\t\t\taddRemoveDelta( this, flat.start, flat.end.offset - flat.start.offset );\n\t\t}\n\t} else {\n\t\taddRemoveDelta( this, Position.createBefore( itemOrRange ), 1 );\n\t}\n\n\treturn this;\n} );\n\nDeltaFactory.register( RemoveDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/removedelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/renamedelta\n */\n\nimport Delta from './delta';\nimport DeltaFactory from './deltafactory';\nimport { register } from '../batch';\nimport RenameOperation from '../operation/renameoperation';\nimport Element from '../element';\nimport Position from '../position';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#rename Batch#rename} method\n * uses the `RenameDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class RenameDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'rename';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn RenameDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.RenameDelta';\n\t}\n}\n\nfunction apply( batch, delta, operation ) {\n\tdelta.addOperation( operation );\n\tbatch.document.applyOperation( operation );\n}\n\n/**\n * Renames given element.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#rename\n * @param {module:engine/model/element~Element} element The element to rename.\n * @param {String} newName New element name.\n */\nregister( 'rename', function( element, newName ) {\n\tif ( !( element instanceof Element ) ) {\n\t\t/**\n\t\t * Trying to rename an object which is not an instance of Element.\n\t\t *\n\t\t * @error batch-rename-not-element-instance\n\t\t */\n\t\tthrow new CKEditorError( 'batch-rename-not-element-instance: Trying to rename an object which is not an instance of Element.' );\n\t}\n\n\tconst delta = new RenameDelta();\n\tthis.addDelta( delta );\n\n\tconst renameOperation = new RenameOperation( Position.createBefore( element ), element.name, newName, this.document.version );\n\tapply( this, delta, renameOperation );\n\n\treturn this;\n} );\n\nDeltaFactory.register( RenameDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/renamedelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/transform\n */\n\nimport InsertOperation from './insertoperation';\nimport AttributeOperation from './attributeoperation';\nimport RootAttributeOperation from './rootattributeoperation';\nimport RenameOperation from './renameoperation';\nimport MarkerOperation from './markeroperation';\nimport MoveOperation from './moveoperation';\nimport RemoveOperation from './removeoperation';\nimport ReinsertOperation from './reinsertoperation';\nimport NoOperation from './nooperation';\nimport Range from '../range';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\n\n/**\n * Transforms given {@link module:engine/model/operation/operation~Operation operation}\n * by another {@link module:engine/model/operation/operation~Operation operation}\n * and returns the result of that transformation as an array containing\n * one or more {@link module:engine/model/operation/operation~Operation operations}.\n *\n * Operations work on specified positions, passed to them when they are created.\n * Whenever {@link module:engine/model/document~Document document}\n * changes, we have to reflect those modifications by updating or \"transforming\" operations which are not yet applied.\n * When an operation is transformed, its parameters may change based on the operation by which it is transformed.\n * If the transform-by operation applied any modifications to the Tree Data Model which affect positions or nodes\n * connected with transformed operation, those changes will be reflected in the parameters of the returned operation(s).\n *\n * Whenever the {@link module:engine/model/document~Document document}\n * has different {@link module:engine/model/document~Document#version}\n * than the operation you want to {@link module:engine/model/document~Document#applyOperation apply}, you need to transform that\n * operation by all operations which were already applied to the {@link module:engine/model/document~Document document} and have greater\n * {@link module:engine/model/document~Document#version} than the operation being applied. Transform them in the same order as those\n * operations which were applied. This way all modifications done to the Tree Data Model will be reflected\n * in the operation parameters and the operation will \"operate\" on \"up-to-date\" version of the Tree Data Model.\n * This is mostly the case with Operational Transformations but it might be needed in particular features as well.\n *\n * In some cases, when given operation apply changes to the same nodes as this operation, two or more operations need\n * to be created as one would not be able to reflect the combination of these operations.\n * This is why an array is returned instead of a single object. All returned operations have to be applied\n * (or further transformed) to get an effect which was intended in pre-transformed operation.\n *\n * Sometimes two operations are in conflict. This happens when they modify the same node in a different way, i.e.\n * set different value for the same attribute or move the node into different positions. When this happens,\n * we need to decide which operation is more important. We can't assume that operation `a` or operation `b` is always\n * more important. In Operational Transformations algorithms we often need to get a result of transforming\n * `a` by `b` and also `b` by `a`. In both transformations the same operation has to be the important one. If we assume\n * that first or the second passed operation is always more important we won't be able to solve this case.\n *\n * @function module:engine/model/operation/transform~transform\n * @param {module:engine/model/operation/operation~Operation} a Operation that will be transformed.\n * @param {module:engine/model/operation/operation~Operation} b Operation to transform by.\n * @param {module:engine/model/delta/transform~transformationContext} [context] Transformation context.\n * @returns {Array.<module:engine/model/operation/operation~Operation>} Result of the transformation.\n */\n\nexport default transform;\n\nconst ot = {\n\tInsertOperation: {\n\t\t// Transforms InsertOperation `a` by InsertOperation `b`. Accepts a flag stating whether `a` is more important\n\t\t// than `b` when it comes to resolving conflicts. Returns results as an array of operations.\n\t\tInsertOperation( a, b, context ) {\n\t\t\t// Transformed operations are always new instances, not references to the original operations.\n\t\t\tconst transformed = a.clone();\n\n\t\t\t// Check whether there is a forced order of nodes or use `context.isStrong` flag for conflict resolving.\n\t\t\tconst insertBefore = context.insertBefore === undefined ? !context.isStrong : context.insertBefore;\n\n\t\t\t// Transform insert position by the other operation position.\n\t\t\ttransformed.position = transformed.position._getTransformedByInsertion( b.position, b.nodes.maxOffset, insertBefore );\n\n\t\t\treturn [ transformed ];\n\t\t},\n\n\t\tAttributeOperation: doNotUpdate,\n\n\t\tRootAttributeOperation: doNotUpdate,\n\n\t\tRenameOperation: doNotUpdate,\n\n\t\tMarkerOperation: doNotUpdate,\n\n\t\t// Transforms InsertOperation `a` by MoveOperation `b`. Accepts a flag stating whether `a` is more important\n\t\t// than `b` when it comes to resolving conflicts. Returns results as an array of operations.\n\t\tMoveOperation( a, b, context ) {\n\t\t\tconst transformed = a.clone();\n\n\t\t\t// Check whether there is a forced order of nodes or use `context.isStrong` flag for conflict resolving.\n\t\t\tconst insertBefore = context.insertBefore === undefined ? !context.isStrong : context.insertBefore;\n\n\t\t\t// Transform insert position by the other operation parameters.\n\t\t\ttransformed.position = a.position._getTransformedByMove(\n\t\t\t\tb.sourcePosition,\n\t\t\t\tb.targetPosition,\n\t\t\t\tb.howMany,\n\t\t\t\tinsertBefore,\n\t\t\t\tb.isSticky && !context.forceNotSticky\n\t\t\t);\n\n\t\t\treturn [ transformed ];\n\t\t}\n\t},\n\n\tAttributeOperation: {\n\t\t// Transforms AttributeOperation `a` by InsertOperation `b`. Returns results as an array of operations.\n\t\tInsertOperation( a, b ) {\n\t\t\t// Transform this operation's range.\n\t\t\tconst ranges = a.range._getTransformedByInsertion( b.position, b.nodes.maxOffset, true, false );\n\n\t\t\t// Map transformed range(s) to operations and return them.\n\t\t\treturn ranges.reverse().map( range => {\n\t\t\t\treturn new AttributeOperation( range, a.key, a.oldValue, a.newValue, a.baseVersion );\n\t\t\t} );\n\t\t},\n\n\t\t// Transforms AttributeOperation `a` by AttributeOperation `b`. Accepts a flag stating whether `a` is more important\n\t\t// than `b` when it comes to resolving conflicts. Returns results as an array of operations.\n\t\tAttributeOperation( a, b, context ) {\n\t\t\tif ( a.key === b.key ) {\n\t\t\t\t// If operations attributes are in conflict, check if their ranges intersect and manage them properly.\n\n\t\t\t\t// First, we want to apply change to the part of a range that has not been changed by the other operation.\n\t\t\t\tconst operations = a.range.getDifference( b.range ).map( range => {\n\t\t\t\t\treturn new AttributeOperation( range, a.key, a.oldValue, a.newValue, a.baseVersion );\n\t\t\t\t} );\n\n\t\t\t\t// Then we take care of the common part of ranges.\n\t\t\t\tconst common = a.range.getIntersection( b.range );\n\n\t\t\t\tif ( common ) {\n\t\t\t\t\t// If this operation is more important, we also want to apply change to the part of the\n\t\t\t\t\t// original range that has already been changed by the other operation. Since that range\n\t\t\t\t\t// got changed we also have to update `oldValue`.\n\t\t\t\t\tif ( context.isStrong ) {\n\t\t\t\t\t\toperations.push( new AttributeOperation( common, b.key, b.newValue, a.newValue, a.baseVersion ) );\n\t\t\t\t\t} else if ( operations.length === 0 ) {\n\t\t\t\t\t\toperations.push( new NoOperation( 0 ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn operations;\n\t\t\t} else {\n\t\t\t\t// If operations don't conflict, simply return an array containing just a clone of this operation.\n\t\t\t\treturn [ a.clone() ];\n\t\t\t}\n\t\t},\n\n\t\tRootAttributeOperation: doNotUpdate,\n\n\t\tRenameOperation: doNotUpdate,\n\n\t\tMarkerOperation: doNotUpdate,\n\n\t\t// Transforms AttributeOperation `a` by MoveOperation `b`. Returns results as an array of operations.\n\t\tMoveOperation( a, b ) {\n\t\t\t// Convert MoveOperation properties into a range.\n\t\t\tconst rangeB = Range.createFromPositionAndShift( b.sourcePosition, b.howMany );\n\n\t\t\t// This will aggregate transformed ranges.\n\t\t\tlet ranges = [];\n\n\t\t\t// Difference is a part of changed range that is modified by AttributeOperation but is not affected\n\t\t\t// by MoveOperation. This can be zero, one or two ranges (if moved range is inside changed range).\n\t\t\t// Right now we will make a simplification and join difference ranges and transform them as one. We will cover rangeB later.\n\t\t\tconst difference = joinRanges( a.range.getDifference( rangeB ) );\n\n\t\t\t// Common is a range of nodes that is affected by MoveOperation. So it got moved to other place.\n\t\t\tconst common = a.range.getIntersection( rangeB );\n\n\t\t\tif ( difference !== null ) {\n\t\t\t\t// MoveOperation removes nodes from their original position. We acknowledge this by proper transformation.\n\t\t\t\t// Take the start and the end of the range and transform them by deletion of moved nodes.\n\t\t\t\t// Note that if rangeB was inside AttributeOperation range, only difference.end will be transformed.\n\t\t\t\t// This nicely covers the joining simplification we did in the previous step.\n\t\t\t\tdifference.start = difference.start._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\t\t\t\tdifference.end = difference.end._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\n\t\t\t\t// MoveOperation pastes nodes into target position. We acknowledge this by proper transformation.\n\t\t\t\t// Note that since we operate on transformed difference range, we should transform by\n\t\t\t\t// previously transformed target position.\n\t\t\t\t// Note that we do not use Position._getTransformedByMove on range boundaries because we need to\n\t\t\t\t// transform by insertion a range as a whole, since newTargetPosition might be inside that range.\n\t\t\t\tranges = difference._getTransformedByInsertion( b.getMovedRangeStart(), b.howMany, true, false ).reverse();\n\t\t\t}\n\n\t\t\tif ( common !== null ) {\n\t\t\t\t// Here we do not need to worry that newTargetPosition is inside moved range, because that\n\t\t\t\t// would mean that the MoveOperation targets into itself, and that is incorrect operation.\n\t\t\t\t// Instead, we calculate the new position of that part of original range.\n\t\t\t\tcommon.start = common.start._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\t\t\t\tcommon.end = common.end._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\n\t\t\t\tranges.push( common );\n\t\t\t}\n\n\t\t\t// Map transformed range(s) to operations and return them.\n\t\t\treturn ranges.map( range => {\n\t\t\t\treturn new AttributeOperation( range, a.key, a.oldValue, a.newValue, a.baseVersion );\n\t\t\t} );\n\t\t}\n\t},\n\n\tRootAttributeOperation: {\n\t\tInsertOperation: doNotUpdate,\n\n\t\tAttributeOperation: doNotUpdate,\n\n\t\t// Transforms RootAttributeOperation `a` by RootAttributeOperation `b`. Accepts a flag stating whether `a` is more important\n\t\t// than `b` when it comes to resolving conflicts. Returns results as an array of operations.\n\t\tRootAttributeOperation( a, b, context ) {\n\t\t\tif ( a.root === b.root && a.key === b.key ) {\n\t\t\t\tif ( ( a.newValue !== b.newValue && !context.isStrong ) || a.newValue === b.newValue ) {\n\t\t\t\t\treturn [ new NoOperation( a.baseVersion ) ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn [ a.clone() ];\n\t\t},\n\n\t\tRenameOperation: doNotUpdate,\n\n\t\tMarkerOperation: doNotUpdate,\n\n\t\tMoveOperation: doNotUpdate\n\t},\n\n\tRenameOperation: {\n\t\t// Transforms RenameOperation `a` by InsertOperation `b`. Returns results as an array of operations.\n\t\tInsertOperation( a, b ) {\n\t\t\t// Clone the operation, we don't want to alter the original operation.\n\t\t\tconst clone = a.clone();\n\n\t\t\t// Transform this operation's position.\n\t\t\tclone.position = clone.position._getTransformedByInsertion( b.position, b.nodes.maxOffset, true );\n\n\t\t\treturn [ clone ];\n\t\t},\n\n\t\tAttributeOperation: doNotUpdate,\n\n\t\tRootAttributeOperation: doNotUpdate,\n\n\t\t// Transforms RenameOperation `a` by RenameOperation `b`. Accepts a flag stating whether `a` is more important\n\t\t// than `b` when it comes to resolving conflicts. Returns results as an array of operations.\n\t\tRenameOperation( a, b, context ) {\n\t\t\t// Clone the operation, we don't want to alter the original operation.\n\t\t\tconst clone = a.clone();\n\n\t\t\tif ( a.position.isEqual( b.position ) ) {\n\t\t\t\tif ( context.isStrong ) {\n\t\t\t\t\tclone.oldName = b.newName;\n\t\t\t\t} else {\n\t\t\t\t\treturn [ new NoOperation( a.baseVersion ) ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn [ clone ];\n\t\t},\n\n\t\tMarkerOperation: doNotUpdate,\n\n\t\t// Transforms RenameOperation `a` by MoveOperation `b`. Returns results as an array of operations.\n\t\tMoveOperation( a, b ) {\n\t\t\tconst clone = a.clone();\n\t\t\tconst isSticky = clone.position.isEqual( b.sourcePosition );\n\n\t\t\tclone.position = clone.position._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany, true, isSticky );\n\n\t\t\treturn [ clone ];\n\t\t}\n\t},\n\n\tMarkerOperation: {\n\t\t// Transforms MarkerOperation `a` by InsertOperation `b`. Returns results as an array of operations.\n\t\tInsertOperation( a, b ) {\n\t\t\t// Clone the operation, we don't want to alter the original operation.\n\t\t\tconst clone = a.clone();\n\n\t\t\tif ( clone.oldRange ) {\n\t\t\t\tclone.oldRange = clone.oldRange._getTransformedByInsertion( b.position, b.nodes.maxOffset, false, false )[ 0 ];\n\t\t\t}\n\n\t\t\tif ( clone.newRange ) {\n\t\t\t\tclone.newRange = clone.newRange._getTransformedByInsertion( b.position, b.nodes.maxOffset, false, false )[ 0 ];\n\t\t\t}\n\n\t\t\treturn [ clone ];\n\t\t},\n\n\t\tAttributeOperation: doNotUpdate,\n\n\t\tRootAttributeOperation: doNotUpdate,\n\n\t\tRenameOperation: doNotUpdate,\n\n\t\t// Transforms MarkerOperation `a` by MarkerOperation `b`. Accepts a flag stating whether `a` is more important\n\t\t// than `b` when it comes to resolving conflicts. Returns results as an array of operations.\n\t\tMarkerOperation( a, b, context ) {\n\t\t\t// Clone the operation, we don't want to alter the original operation.\n\t\t\tconst clone = a.clone();\n\n\t\t\tif ( a.name == b.name ) {\n\t\t\t\tif ( context.isStrong ) {\n\t\t\t\t\tclone.oldRange = b.newRange;\n\t\t\t\t} else {\n\t\t\t\t\treturn [ new NoOperation( a.baseVersion ) ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn [ clone ];\n\t\t},\n\n\t\t// Transforms MarkerOperation `a` by MoveOperation `b`. Returns results as an array of operations.\n\t\tMoveOperation( a, b ) {\n\t\t\t// Clone the operation, we don't want to alter the original operation.\n\t\t\tconst clone = a.clone();\n\n\t\t\tif ( clone.oldRange ) {\n\t\t\t\tconst oldRanges = clone.oldRange._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\t\t\t\tclone.oldRange = Range.createFromRanges( oldRanges );\n\t\t\t}\n\n\t\t\tif ( clone.newRange ) {\n\t\t\t\tconst newRanges = clone.newRange._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\t\t\t\tclone.newRange = Range.createFromRanges( newRanges );\n\t\t\t}\n\n\t\t\treturn [ clone ];\n\t\t}\n\t},\n\n\tMoveOperation: {\n\t\t// Transforms MoveOperation `a` by InsertOperation `b`. Accepts a flag stating whether `a` is more important\n\t\t// than `b` when it comes to resolving conflicts. Returns results as an array of operations.\n\t\tInsertOperation( a, b, context ) {\n\t\t\t// Create range from MoveOperation properties and transform it by insertion.\n\t\t\tlet range = Range.createFromPositionAndShift( a.sourcePosition, a.howMany );\n\t\t\tconst includeB = a.isSticky && !context.forceNotSticky;\n\n\t\t\trange = range._getTransformedByInsertion( b.position, b.nodes.maxOffset, false, includeB )[ 0 ];\n\n\t\t\t// Check whether there is a forced order of nodes or use `context.isStrong` flag for conflict resolving.\n\t\t\tconst insertBefore = context.insertBefore === undefined ? !context.isStrong : context.insertBefore;\n\n\t\t\tconst result = new a.constructor(\n\t\t\t\trange.start,\n\t\t\t\trange.end.offset - range.start.offset,\n\t\t\t\ta.targetPosition._getTransformedByInsertion( b.position, b.nodes.maxOffset, insertBefore ),\n\t\t\t\ta.baseVersion\n\t\t\t);\n\n\t\t\tresult.isSticky = a.isSticky;\n\n\t\t\treturn [ result ];\n\t\t},\n\n\t\tAttributeOperation: doNotUpdate,\n\n\t\tRootAttributeOperation: doNotUpdate,\n\n\t\tRenameOperation: doNotUpdate,\n\n\t\tMarkerOperation: doNotUpdate,\n\n\t\t// Transforms MoveOperation `a` by MoveOperation `b`. Accepts a flag stating whether `a` is more important\n\t\t// than `b` when it comes to resolving conflicts. Returns results as an array of operations.\n\t\tMoveOperation( a, b, context ) {\n\t\t\t//\n\t\t\t// Setting and evaluating some variables that will be used in special cases and default algorithm.\n\t\t\t//\n\t\t\t// Create ranges from `MoveOperations` properties.\n\t\t\tconst rangeA = Range.createFromPositionAndShift( a.sourcePosition, a.howMany );\n\t\t\tconst rangeB = Range.createFromPositionAndShift( b.sourcePosition, b.howMany );\n\n\t\t\t// Assign `context.isStrong` to a different variable, because the value may change during execution of\n\t\t\t// this algorithm and we do not want to override original `context.isStrong` that will be used in later transformations.\n\t\t\tlet isStrong = context.isStrong;\n\n\t\t\t// Whether range moved by operation `b` is includable in operation `a` move range.\n\t\t\t// For this, `a` operation has to be sticky (so `b` sticks to the range) and context has to allow stickiness.\n\t\t\tconst includeB = a.isSticky && !context.forceNotSticky;\n\n\t\t\t// Evaluate new target position for transformed operation.\n\t\t\t// Check whether there is a forced order of nodes or use `isStrong` flag for conflict resolving.\n\t\t\tconst insertBefore = context.insertBefore === undefined ? !isStrong : context.insertBefore;\n\n\t\t\t// `a.targetPosition` could be affected by the `b` operation. We will transform it.\n\t\t\tconst newTargetPosition = a.targetPosition._getTransformedByMove(\n\t\t\t\tb.sourcePosition,\n\t\t\t\tb.targetPosition,\n\t\t\t\tb.howMany,\n\t\t\t\tinsertBefore,\n\t\t\t\tb.isSticky && !context.forceNotSticky\n\t\t\t);\n\n\t\t\t//\n\t\t\t// Special case #1 + mirror.\n\t\t\t//\n\t\t\t// Special case when both move operations' target positions are inside nodes that are\n\t\t\t// being moved by the other move operation. So in other words, we move ranges into inside of each other.\n\t\t\t// This case can't be solved reasonably (on the other hand, it should not happen often).\n\t\t\tif ( moveTargetIntoMovedRange( a, b ) && moveTargetIntoMovedRange( b, a ) ) {\n\t\t\t\t// Instead of transforming operation, we return a reverse of the operation that we transform by.\n\t\t\t\t// So when the results of this \"transformation\" will be applied, `b` MoveOperation will get reversed.\n\t\t\t\treturn [ b.getReversed() ];\n\t\t\t}\n\t\t\t//\n\t\t\t// End of special case #1.\n\t\t\t//\n\n\t\t\t//\n\t\t\t// Special case #2.\n\t\t\t//\n\t\t\t// Check if `b` operation targets inside `rangeA`. Use stickiness if possible.\n\t\t\tconst bTargetsToA = rangeA.containsPosition( b.targetPosition ) ||\n\t\t\t\t( rangeA.start.isEqual( b.targetPosition ) && includeB ) ||\n\t\t\t\t( rangeA.end.isEqual( b.targetPosition ) && includeB );\n\n\t\t\t// If `b` targets to `rangeA` and `rangeA` contains `rangeB`, `b` operation has no influence on `a` operation.\n\t\t\t// You might say that operation `b` is captured inside operation `a`.\n\t\t\tif ( bTargetsToA && rangeA.containsRange( rangeB, true ) ) {\n\t\t\t\t// There is a mini-special case here, where `rangeB` is on other level than `rangeA`. That's why\n\t\t\t\t// we need to transform `a` operation anyway.\n\t\t\t\trangeA.start = rangeA.start._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany, !includeB );\n\t\t\t\trangeA.end = rangeA.end._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany, includeB );\n\n\t\t\t\treturn makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition, a );\n\t\t\t}\n\n\t\t\t//\n\t\t\t// Special case #2 mirror.\n\t\t\t//\n\t\t\tconst aTargetsToB = rangeB.containsPosition( a.targetPosition ) ||\n\t\t\t\t( rangeB.start.isEqual( a.targetPosition ) && b.isSticky && !context.forceNotSticky ) ||\n\t\t\t\t( rangeB.end.isEqual( a.targetPosition ) && b.isSticky && !context.forceNotSticky );\n\n\t\t\tif ( aTargetsToB && rangeB.containsRange( rangeA, true ) ) {\n\t\t\t\t// `a` operation is \"moved together\" with `b` operation.\n\t\t\t\t// Here, just move `rangeA` \"inside\" `rangeB`.\n\t\t\t\trangeA.start = rangeA.start._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\t\t\t\trangeA.end = rangeA.end._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\n\t\t\t\treturn makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition, a );\n\t\t\t}\n\t\t\t//\n\t\t\t// End of special case #2.\n\t\t\t//\n\n\t\t\t//\n\t\t\t// Special case #3 + mirror.\n\t\t\t//\n\t\t\t// `rangeA` has a node which is an ancestor of `rangeB`. In other words, `rangeB` is inside `rangeA`\n\t\t\t// but not on the same tree level. In such case ranges have common part but we have to treat it\n\t\t\t// differently, because in such case those ranges are not really conflicting and should be treated like\n\t\t\t// two separate ranges. Also we have to discard two difference parts.\n\t\t\tconst aCompB = compareArrays( a.sourcePosition.getParentPath(), b.sourcePosition.getParentPath() );\n\n\t\t\tif ( aCompB == 'prefix' || aCompB == 'extension' ) {\n\t\t\t\t// Transform `rangeA` by `b` operation and make operation out of it, and that's all.\n\t\t\t\t// Note that this is a simplified version of default case, but here we treat the common part (whole `rangeA`)\n\t\t\t\t// like a one difference part.\n\t\t\t\trangeA.start = rangeA.start._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany, !includeB );\n\t\t\t\trangeA.end = rangeA.end._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany, includeB );\n\n\t\t\t\treturn makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition, a );\n\t\t\t}\n\t\t\t//\n\t\t\t// End of special case #3.\n\t\t\t//\n\n\t\t\t//\n\t\t\t// Default case - ranges are on the same level or are not connected with each other.\n\t\t\t//\n\t\t\t// Modifier for default case.\n\t\t\t// Modifies `isStrong` flag in certain conditions.\n\t\t\t//\n\t\t\t// If only one of operations is a remove operation, we force remove operation to be the \"stronger\" one\n\t\t\t// to provide more expected results. This is done only if `context.forceWeakRemove` is set to `false`.\n\t\t\t// `context.forceWeakRemove` is set to `true` in certain conditions when transformation takes place during undo.\n\t\t\tif ( !context.forceWeakRemove ) {\n\t\t\t\tif ( a instanceof RemoveOperation && !( b instanceof RemoveOperation ) ) {\n\t\t\t\t\tisStrong = true;\n\t\t\t\t} else if ( !( a instanceof RemoveOperation ) && b instanceof RemoveOperation ) {\n\t\t\t\t\tisStrong = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Handle operation's source ranges - check how `rangeA` is affected by `b` operation.\n\t\t\t// This will aggregate transformed ranges.\n\t\t\tconst ranges = [];\n\n\t\t\t// Get the \"difference part\" of `a` operation source range.\n\t\t\t// This is an array with one or two ranges. Two ranges if `rangeB` is inside `rangeA`.\n\t\t\tconst difference = rangeA.getDifference( rangeB );\n\n\t\t\tfor ( const range of difference ) {\n\t\t\t\t// Transform those ranges by `b` operation. For example if `b` moved range from before those ranges, fix those ranges.\n\t\t\t\trange.start = range.start._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\t\t\t\trange.end = range.end._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\n\t\t\t\t// If `b` operation targets into `rangeA` on the same level, spread `rangeA` into two ranges.\n\t\t\t\tconst shouldSpread = compareArrays( range.start.getParentPath(), b.getMovedRangeStart().getParentPath() ) == 'same';\n\t\t\t\tconst newRanges = range._getTransformedByInsertion( b.getMovedRangeStart(), b.howMany, shouldSpread, includeB );\n\n\t\t\t\tranges.push( ...newRanges );\n\t\t\t}\n\n\t\t\t// Then, we have to manage the \"common part\" of both move ranges.\n\t\t\tconst common = rangeA.getIntersection( rangeB );\n\n\t\t\tif ( common !== null && isStrong && !bTargetsToA ) {\n\t\t\t\t// Calculate the new position of that part of original range.\n\t\t\t\tcommon.start = common.start._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\t\t\t\tcommon.end = common.end._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\n\t\t\t\t// Take care of proper range order.\n\t\t\t\t//\n\t\t\t\t// Put `common` at appropriate place. Keep in mind that we are interested in original order.\n\t\t\t\t// Basically there are only three cases: there is zero, one or two difference ranges.\n\t\t\t\t//\n\t\t\t\t// If there is zero difference ranges, just push `common` in the array.\n\t\t\t\tif ( ranges.length === 0 ) {\n\t\t\t\t\tranges.push( common );\n\t\t\t\t}\n\t\t\t\t// If there is one difference range, we need to check whether common part was before it or after it.\n\t\t\t\telse if ( ranges.length == 1 ) {\n\t\t\t\t\tif ( rangeB.start.isBefore( rangeA.start ) || rangeB.start.isEqual( rangeA.start ) ) {\n\t\t\t\t\t\tranges.unshift( common );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tranges.push( common );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If there are more ranges (which means two), put common part between them. This is the only scenario\n\t\t\t\t// where there could be two difference ranges so we don't have to make any comparisons.\n\t\t\t\telse {\n\t\t\t\t\tranges.splice( 1, 0, common );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( ranges.length === 0 ) {\n\t\t\t\t// If there are no \"source ranges\", nothing should be changed.\n\t\t\t\t// Note that this can happen only if `isStrong == false` and `rangeA.isEqual( rangeB )`.\n\t\t\t\treturn [ new NoOperation( a.baseVersion ) ];\n\t\t\t}\n\n\t\t\treturn makeMoveOperationsFromRanges( ranges, newTargetPosition, a );\n\t\t}\n\t}\n};\n\nfunction transform( a, b, context = { isStrong: false } ) {\n\tlet group, algorithm;\n\n\tif ( a instanceof InsertOperation ) {\n\t\tgroup = ot.InsertOperation;\n\t} else if ( a instanceof AttributeOperation ) {\n\t\tgroup = ot.AttributeOperation;\n\t} else if ( a instanceof RootAttributeOperation ) {\n\t\tgroup = ot.RootAttributeOperation;\n\t} else if ( a instanceof RenameOperation ) {\n\t\tgroup = ot.RenameOperation;\n\t} else if ( a instanceof MarkerOperation ) {\n\t\tgroup = ot.MarkerOperation;\n\t} else if ( a instanceof MoveOperation ) {\n\t\tgroup = ot.MoveOperation;\n\t} else {\n\t\talgorithm = doNotUpdate;\n\t}\n\n\tif ( group ) {\n\t\tif ( b instanceof InsertOperation ) {\n\t\t\talgorithm = group.InsertOperation;\n\t\t} else if ( b instanceof AttributeOperation ) {\n\t\t\talgorithm = group.AttributeOperation;\n\t\t} else if ( b instanceof RootAttributeOperation ) {\n\t\t\talgorithm = group.RootAttributeOperation;\n\t\t} else if ( b instanceof RenameOperation ) {\n\t\t\talgorithm = group.RenameOperation;\n\t\t} else if ( b instanceof MarkerOperation ) {\n\t\t\talgorithm = group.MarkerOperation;\n\t\t} else if ( b instanceof MoveOperation ) {\n\t\t\talgorithm = group.MoveOperation;\n\t\t} else {\n\t\t\talgorithm = doNotUpdate;\n\t\t}\n\t}\n\n\tconst transformed = algorithm( a, b, context );\n\n\treturn updateBaseVersions( a.baseVersion, transformed );\n}\n\n// When we don't want to update an operation, we create and return a clone of it.\n// Returns the operation in \"unified format\" - wrapped in an Array.\nfunction doNotUpdate( operation ) {\n\treturn [ operation.clone() ];\n}\n\n// Takes an Array of operations and sets consecutive base versions for them, starting from given base version.\n// Returns the passed array.\nfunction updateBaseVersions( baseVersion, operations ) {\n\tfor ( let i = 0; i < operations.length; i++ ) {\n\t\toperations[ i ].baseVersion = baseVersion + i + 1;\n\t}\n\n\treturn operations;\n}\n\n// Checks whether MoveOperation targetPosition is inside a node from the moved range of the other MoveOperation.\nfunction moveTargetIntoMovedRange( a, b ) {\n\treturn a.targetPosition._getTransformedByDeletion( b.sourcePosition, b.howMany ) === null;\n}\n\n// Gets an array of Ranges and produces one Range out of it. The root of a new range will be same as\n// the root of the first range in the array. If any of given ranges has different root than the first range,\n// it will be discarded.\nfunction joinRanges( ranges ) {\n\tif ( ranges.length === 0 ) {\n\t\treturn null;\n\t} else if ( ranges.length == 1 ) {\n\t\treturn ranges[ 0 ];\n\t} else {\n\t\tranges[ 0 ].end = ranges[ ranges.length - 1 ].end;\n\n\t\treturn ranges[ 0 ];\n\t}\n}\n\n// Helper function for `MoveOperation` x `MoveOperation` transformation.\n// Convert given ranges and target position to move operations and return them.\n// Ranges and target position will be transformed on-the-fly when generating operations.\n// Given `ranges` should be in the order of how they were in the original transformed operation.\n// Given `targetPosition` is the target position of the first range from `ranges`.\nfunction makeMoveOperationsFromRanges( ranges, targetPosition, a ) {\n\t// At this moment we have some ranges and a target position, to which those ranges should be moved.\n\t// Order in `ranges` array is the go-to order of after transformation.\n\t//\n\t// We are almost done. We have `ranges` and `targetPosition` to make operations from.\n\t// Unfortunately, those operations may affect each other. Precisely, first operation after move\n\t// may affect source range and target position of second and third operation. Same with second\n\t// operation affecting third.\n\t//\n\t// We need to fix those source ranges and target positions once again, before converting `ranges` to operations.\n\tconst operations = [];\n\n\t// Keep in mind that nothing will be transformed if there is just one range in `ranges`.\n\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t// Create new operation out of a range and target position.\n\t\tconst op = makeMoveOperation( ranges[ i ], targetPosition, a.isSticky );\n\n\t\toperations.push( op );\n\n\t\t// Transform other ranges by the generated operation.\n\t\tfor ( let j = i + 1; j < ranges.length; j++ ) {\n\t\t\t// All ranges in `ranges` array should be:\n\t\t\t// * non-intersecting (these are part of original operation source range), and\n\t\t\t// * `targetPosition` does not target into them (opposite would mean that transformed operation targets \"inside itself\").\n\t\t\t//\n\t\t\t// This means that the transformation will be \"clean\" and always return one result.\n\t\t\tranges[ j ] = ranges[ j ]._getTransformedByMove( op.sourcePosition, op.targetPosition, op.howMany )[ 0 ];\n\t\t}\n\n\t\ttargetPosition = targetPosition._getTransformedByMove( op.sourcePosition, op.targetPosition, op.howMany, true, false );\n\t}\n\n\treturn operations;\n}\n\nfunction makeMoveOperation( range, targetPosition, isSticky ) {\n\t// We want to keep correct operation class.\n\tlet OperationClass;\n\n\tif ( targetPosition.root.rootName == '$graveyard' ) {\n\t\tOperationClass = RemoveOperation;\n\t} else if ( range.start.root.rootName == '$graveyard' ) {\n\t\tOperationClass = ReinsertOperation;\n\t} else {\n\t\tOperationClass = MoveOperation;\n\t}\n\n\tconst result = new OperationClass(\n\t\trange.start,\n\t\trange.end.offset - range.start.offset,\n\t\ttargetPosition,\n\t\t0 // Is corrected anyway later.\n\t);\n\n\tresult.isSticky = isSticky;\n\n\treturn result;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/transform.js\n// module id = null\n// module chunks = ","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseSlice.js\n// module id = null\n// module chunks = ","import arrayPush from './_arrayPush';\nimport isFlattenable from './_isFlattenable';\n\n/**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\nfunction baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n}\n\nexport default baseFlatten;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseFlatten.js\n// module id = null\n// module chunks = ","import MapCache from './_MapCache';\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result);\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Assign cache to `_.memoize`.\nmemoize.Cache = MapCache;\n\nexport default memoize;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/memoize.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @protected\n * @module engine/model/delta/transform\n */\n\nimport Delta from './delta';\nimport MoveDelta from './movedelta';\nimport RemoveDelta from './removedelta';\nimport MergeDelta from './mergedelta';\nimport SplitDelta from './splitdelta';\nimport WrapDelta from './wrapdelta';\nimport UnwrapDelta from './unwrapdelta';\nimport RenameDelta from './renamedelta';\nimport AttributeDelta from './attributedelta';\nimport operationTransform from '../operation/transform';\nimport NoOperation from '../operation/nooperation';\nimport MoveOperation from '../operation/moveoperation';\nimport RemoveOperation from '../operation/removeoperation';\nimport arrayUtils from '@ckeditor/ckeditor5-utils/src/lib/lodash/array';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\n\nconst specialCases = new Map();\n\n/**\n * @namespace\n */\nconst transform = {\n\t/**\n\t * Transforms given {@link module:engine/model/delta/delta~Delta delta} by another {@link module:engine/model/delta/delta~Delta delta}\n\t * and returns the result of that transformation as an array containing one or more {@link module:engine/model/delta/delta~Delta delta}\n\t * instances.\n\t *\n\t * Delta transformations heavily base on {@link module:engine/model/operation/transform~transform operational transformations}. Since\n\t * delta is a list of operations most situations can be handled thanks to operational transformation. Unfortunately,\n\t * deltas are more complicated than operations and have they semantic meaning, as they represent user's editing intentions.\n\t *\n\t * Sometimes, simple operational transformation on deltas' operations might result in some unexpected results. Those\n\t * results would be fine from OT point of view, but would not reflect user's intentions. Because of such conflicts\n\t * we need to handle transformations in special cases in a custom way.\n\t *\n\t * The function itself looks whether two given delta types have a special case function registered. If so, the deltas are\n\t * transformed using that function. If not,\n\t * {@link module:engine/model/delta/transform~transform.defaultTransform default transformation algorithm} is used.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} a Delta that will be transformed.\n\t * @param {module:engine/model/delta/delta~Delta} b Delta to transform by.\n\t * @param {module:engine/model/delta/transform~transformationContext} context Transformation context object.\n\t * @returns {Array.<module:engine/model/delta/delta~Delta>} Result of the transformation.\n\t */\n\ttransform( a, b, context ) {\n\t\tconst transformAlgorithm = transform.getTransformationCase( a, b ) || transform.defaultTransform;\n\n\t\t// Make new instance of context object, so all changes done during transformation are not saved in original object.\n\t\tconst transformed = transformAlgorithm( a, b, Object.assign( {}, context ) );\n\t\tconst baseVersion = arrayUtils.last( b.operations ).baseVersion;\n\n\t\treturn updateBaseVersion( baseVersion, transformed );\n\t},\n\n\t/**\n\t * The default delta transformation function. It is used for those deltas that are not in special case conflict.\n\t *\n\t * This algorithm is similar to a popular `dOPT` algorithm used in operational transformation, as we are in fact\n\t * transforming two sets of operations by each other.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} a Delta that will be transformed.\n\t * @param {module:engine/model/delta/delta~Delta} b Delta to transform by.\n\t * @param {module:engine/model/delta/transform~transformationContext} context Transformation context object.\n\t * @returns {Array.<module:engine/model/delta/delta~Delta>} Result of the transformation.\n\t */\n\tdefaultTransform( a, b, context ) {\n\t\t// This will hold operations from delta `a` that will be transformed by operations from delta `b`.\n\t\t// Eventually, those operations will be used to create result delta(s).\n\t\tconst transformed = [];\n\n\t\t// Array containing operations that we will transform by. At the beginning these are just operations from\n\t\tlet byOps = b.operations;\n\n\t\t// This array is storing operations from `byOps` which got transformed by operation from delta `a`.\n\t\tlet newByOps = [];\n\n\t\t// We take each operation from original set of operations to transform.\n\t\tfor ( const opA of a.operations ) {\n\t\t\t// We wrap the operation in the array. This is important, because operation transformation algorithm returns\n\t\t\t// an array of operations so we need to make sure that our algorithm is ready to handle arrays.\n\t\t\tconst ops = [ opA ];\n\n\t\t\t// Now the real algorithm takes place.\n\t\t\tfor ( const opB of byOps ) {\n\t\t\t\t// For each operation that we need transform by...\n\t\t\t\tfor ( let i = 0; i < ops.length; i++ ) {\n\t\t\t\t\t// We take each operation to transform...\n\t\t\t\t\tconst op = ops[ i ];\n\n\t\t\t\t\t// And transform both of them by themselves.\n\n\t\t\t\t\t// The result of transforming operation from delta B by operation from delta A is saved in\n\t\t\t\t\t// `newByOps` array. We will use that array for transformations in next loops. We need delta B\n\t\t\t\t\t// operations after transformed by delta A operations to get correct results of transformations\n\t\t\t\t\t// of next operations from delta A.\n\t\t\t\t\t//\n\t\t\t\t\t// It's like this because 2nd operation from delta A assumes that 1st operation from delta A\n\t\t\t\t\t// is \"already applied\". When we transform 2nd operation from delta A by operations from delta B\n\t\t\t\t\t// we have to be sure that operations from delta B are in a state that acknowledges 1st operation\n\t\t\t\t\t// from delta A.\n\t\t\t\t\t//\n\t\t\t\t\t// This can be easier understood when operations sets to transform are represented by diamond diagrams:\n\t\t\t\t\t// http://www.codecommit.com/blog/java/understanding-and-applying-operational-transformation\n\n\t\t\t\t\t// Transform operation from delta A by operation from delta B.\n\t\t\t\t\tconst results = operationTransform( op, opB, context );\n\n\t\t\t\t\t// We replace currently processed operation from `ops` array by the results of transformation.\n\t\t\t\t\t// Note, that we process single operation but `operationTransform` result is an array, so we\n\t\t\t\t\t// might have to splice-in more than one operation. Save them in `ops` array and move `i` pointer by a proper offset.\n\t\t\t\t\tArray.prototype.splice.apply( ops, [ i, 1 ].concat( results ) );\n\n\t\t\t\t\ti += results.length - 1;\n\n\t\t\t\t\t// Then, transform operation from delta B by operation from delta A.\n\t\t\t\t\t// Since this is a \"mirror\" transformation, first, we \"mirror\" some of context values.\n\t\t\t\t\tconst reverseContext = Object.assign( {}, context );\n\t\t\t\t\treverseContext.isStrong = !context.isStrong;\n\t\t\t\t\treverseContext.insertBefore = context.insertBefore !== undefined ? !context.insertBefore : undefined;\n\n\t\t\t\t\t// Transform operations.\n\t\t\t\t\tconst updatedOpB = operationTransform( opB, op, reverseContext );\n\n\t\t\t\t\t// Update `newByOps` by transformed, updated `opB`.\n\t\t\t\t\t// Using push.apply because `operationTransform` returns an array with one or multiple results.\n\t\t\t\t\tArray.prototype.push.apply( newByOps, updatedOpB );\n\t\t\t\t}\n\n\t\t\t\t// At this point a single operation from delta A got transformed by a single operation from delta B.\n\t\t\t\t// The transformation result is in `ops` array and it may be one or more operations. This was just the first step.\n\t\t\t\t// Operation from delta A has to be further transformed by the other operations from delta B.\n\t\t\t\t// So in next iterator loop we will take another operation from delta B and use transformed delta A (`ops`)\n\t\t\t\t// to transform it further.\n\t\t\t}\n\n\t\t\t// We got through all delta B operations and have a final transformed state of an operation from delta A.\n\n\t\t\t// As previously mentioned, we substitute operations from delta B by their transformed equivalents.\n\t\t\tbyOps = newByOps;\n\t\t\tnewByOps = [];\n\n\t\t\t// We add transformed operation from delta A to newly created delta.\n\t\t\t// Remember that transformed operation from delta A may consist of multiple operations.\n\t\t\tfor ( const op of ops ) {\n\t\t\t\ttransformed.push( op );\n\t\t\t}\n\n\t\t\t// In next loop, we will take another operation from delta A and transform it through (transformed) operations\n\t\t\t// from delta B...\n\t\t}\n\n\t\treturn getNormalizedDeltas( a.constructor, transformed );\n\t},\n\n\t/**\n\t * Adds a special case callback for given delta classes.\n\t *\n\t * @param {Function} A Delta constructor which instance will get transformed.\n\t * @param {Function} B Delta constructor which instance will be transformed by.\n\t * @param {Function} resolver A callback that will handle custom special case transformation for instances of given delta classes.\n\t */\n\taddTransformationCase( A, B, resolver ) {\n\t\tlet casesA = specialCases.get( A );\n\n\t\tif ( !casesA ) {\n\t\t\tcasesA = new Map();\n\t\t\tspecialCases.set( A, casesA );\n\t\t}\n\n\t\tcasesA.set( B, resolver );\n\t},\n\n\t/**\n\t * Gets a special case callback which was previously {@link module:engine/model/delta/transform~transform.addTransformationCase added}.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} a Delta to transform.\n\t * @param {module:engine/model/delta/delta~Delta} b Delta to be transformed by.\n\t */\n\tgetTransformationCase( a, b ) {\n\t\tlet casesA = specialCases.get( a.constructor );\n\n\t\t// If there are no special cases registered for class which `a` is instance of, we will\n\t\t// check if there are special cases registered for any parent class.\n\t\tif ( !casesA || !casesA.get( b.constructor ) ) {\n\t\t\tconst cases = specialCases.keys();\n\n\t\t\tfor ( const caseClass of cases ) {\n\t\t\t\tif ( a instanceof caseClass && specialCases.get( caseClass ).get( b.constructor ) ) {\n\t\t\t\t\tcasesA = specialCases.get( caseClass );\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( casesA ) {\n\t\t\treturn casesA.get( b.constructor );\n\t\t}\n\n\t\treturn undefined;\n\t},\n\n\t/**\n\t * Transforms two sets of deltas by themselves. Returns both transformed sets.\n\t *\n\t * @param {Array.<module:engine/model/delta/delta~Delta>} deltasA Array with the first set of deltas to transform. These\n\t * deltas are considered more important (than `deltasB`) when resolving conflicts.\n\t * @param {Array.<module:engine/model/delta/delta~Delta>} deltasB Array with the second set of deltas to transform. These\n\t * deltas are considered less important (than `deltasA`) when resolving conflicts.\n\t * @param {module:engine/model/document~Document} [document=null] If set, deltas will be transformed in \"undo mode\"\n\t * and given `document` will be used to determine relations between deltas. If not set (default), deltas will be\n\t * transforming without additional context information.\n\t * @returns {Object}\n\t * @returns {Array.<module:engine/model/delta/delta~Delta>} return.deltasA The first set of deltas transformed\n\t * by the second set of deltas.\n\t * @returns {Array.<module:engine/model/delta/delta~Delta>} return.deltasB The second set of deltas transformed\n\t * by the first set of deltas.\n\t */\n\ttransformDeltaSets( deltasA, deltasB, document = null ) {\n\t\tconst transformedDeltasA = Array.from( deltasA );\n\t\tconst transformedDeltasB = Array.from( deltasB );\n\n\t\tconst useAdditionalContext = document !== null;\n\n\t\tconst contextAB = {\n\t\t\tisStrong: true\n\t\t};\n\n\t\tif ( useAdditionalContext ) {\n\t\t\tcontextAB.wasAffected = new Map();\n\t\t\tcontextAB.originalDelta = new Map();\n\t\t\tcontextAB.document = document;\n\t\t\tcontextAB.undoMode = true;\n\n\t\t\tfor ( const delta of transformedDeltasB ) {\n\t\t\t\tcontextAB.originalDelta.set( delta, delta );\n\t\t\t}\n\t\t}\n\n\t\tfor ( let i = 0; i < transformedDeltasA.length; i++ ) {\n\t\t\tconst deltaA = [ transformedDeltasA[ i ] ];\n\n\t\t\tfor ( let j = 0; j < transformedDeltasB.length; j++ ) {\n\t\t\t\tconst deltaB = [ transformedDeltasB[ j ] ];\n\n\t\t\t\tfor ( let k = 0; k < deltaA.length; k++ ) {\n\t\t\t\t\tfor ( let l = 0; l < deltaB.length; l++ ) {\n\t\t\t\t\t\tif ( useAdditionalContext ) {\n\t\t\t\t\t\t\t_setContext( deltaA[ k ], deltaB[ l ], contextAB );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst resultAB = transform.transform( deltaA[ k ], deltaB[ l ], {\n\t\t\t\t\t\t\tinsertBefore: contextAB.insertBefore,\n\t\t\t\t\t\t\tforceNotSticky: contextAB.forceNotSticky,\n\t\t\t\t\t\t\tisStrong: contextAB.isStrong,\n\t\t\t\t\t\t\tforceWeakRemove: contextAB.forceWeakRemove,\n\t\t\t\t\t\t\tundoMode: contextAB.undoMode\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\tconst resultBA = transform.transform( deltaB[ l ], deltaA[ k ], {\n\t\t\t\t\t\t\tinsertBefore: !contextAB.insertBefore,\n\t\t\t\t\t\t\tforceNotSticky: contextAB.forceNotSticky,\n\t\t\t\t\t\t\tisStrong: !contextAB.isStrong,\n\t\t\t\t\t\t\tforceWeakRemove: contextAB.forceWeakRemove,\n\t\t\t\t\t\t\tundoMode: contextAB.undoMode\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\tif ( useAdditionalContext ) {\n\t\t\t\t\t\t\t_updateContext( deltaA[ k ], resultAB, contextAB );\n\n\t\t\t\t\t\t\tconst originalDelta = contextAB.originalDelta.get( deltaB[ l ] );\n\n\t\t\t\t\t\t\tfor ( const deltaBA of resultBA ) {\n\t\t\t\t\t\t\t\tcontextAB.originalDelta.set( deltaBA, originalDelta );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeltaA.splice( k, 1, ...resultAB );\n\t\t\t\t\t\tk += resultAB.length - 1;\n\n\t\t\t\t\t\tdeltaB.splice( l, 1, ...resultBA );\n\t\t\t\t\t\tl += resultBA.length - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttransformedDeltasB.splice( j, 1, ...deltaB );\n\t\t\t\tj += deltaB.length - 1;\n\t\t\t}\n\n\t\t\ttransformedDeltasA.splice( i, 1, ...deltaA );\n\t\t\ti += deltaA.length - 1;\n\t\t}\n\n\t\tconst opsDiffA = getOpsCount( transformedDeltasA ) - getOpsCount( deltasA );\n\t\tconst opsDiffB = getOpsCount( transformedDeltasB ) - getOpsCount( deltasB );\n\n\t\tif ( opsDiffB < opsDiffA ) {\n\t\t\tpadWithNoOps( transformedDeltasB, opsDiffA - opsDiffB );\n\t\t} else if ( opsDiffA < opsDiffB ) {\n\t\t\tpadWithNoOps( transformedDeltasA, opsDiffB - opsDiffA );\n\t\t}\n\n\t\treturn { deltasA: transformedDeltasA, deltasB: transformedDeltasB };\n\t}\n};\n\nexport default transform;\n\n// Updates base versions of operations inside deltas (which are the results of delta transformation).\nfunction updateBaseVersion( baseVersion, deltas ) {\n\tfor ( const delta of deltas ) {\n\t\tfor ( const op of delta.operations ) {\n\t\t\top.baseVersion = ++baseVersion;\n\t\t}\n\t}\n\n\treturn deltas;\n}\n\n// Returns number of operations in given array of deltas.\nfunction getOpsCount( deltas ) {\n\treturn deltas.reduce( ( current, delta ) => {\n\t\treturn current + delta.operations.length;\n\t}, 0 );\n}\n\n// Adds a delta containing `howMany` `NoOperation` instances to given array with deltas.\n// Used to \"synchronize\" the number of operations in two delta sets.\nfunction padWithNoOps( deltas, howMany ) {\n\tconst lastDelta = deltas[ deltas.length - 1 ];\n\tlet baseVersion = lastDelta.operations.length + lastDelta.baseVersion;\n\n\tconst noDelta = new Delta();\n\n\tfor ( let i = 0; i < howMany; i++ ) {\n\t\tnoDelta.addOperation( new NoOperation( baseVersion++ ) );\n\t}\n\n\tdeltas.push( noDelta );\n}\n\n// Sets context data before delta `a` by delta `b` transformation.\n// Using data given in `context` object, sets `context.insertBefore` and `context.forceNotSticky` flags.\n// Also updates `context.wasAffected`.\nfunction _setContext( a, b, context ) {\n\t_setWasAffected( a, b, context );\n\t_setInsertBeforeContext( a, b, context );\n\t_setForceWeakRemove( b, context );\n\t_setForceNotSticky( b, context );\n}\n\n// Sets `context.insertBefore` basing on `context.document` history for `a` by `b` transformation.\n//\n// Simply saying, if `b` is \"undoing delta\" it means that `a` might already be transformed by the delta\n// which was undone by `b` (let's call it `oldB`). If this is true, `a` by `b` transformation has to consider\n// how `a` was transformed by `oldB` to get an expected result.\n//\n// This is used to resolve conflict when two operations want to insert nodes at the same position. If the operations\n// are not related, it doesn't matter in what order operations insert those nodes. However if the operations are\n// related (for example, in undo) we need to keep the same order.\n//\n// For example, assume that editor has two letters: 'ab'. Then, both letters are removed, creating two operations:\n// (op. 1) REM [ 1 ] - [ 2 ] => (graveyard) [ 0 ]\n// (op. 2) REM [ 0 ] - [ 1 ] => (graveyard) [ 1 ]\n// Then, we undo operation 2:\n// REM [ 0 ] - [ 1 ] => (graveyard) [ 1 ] is reversed to REI (graveyard) [ 1 ] => [ 0 ] - [ 1 ] and is applied.\n// History stack is:\n// (op. 1) REM [ 1 ] - [ 2 ] => (graveyard) [ 0 ]\n// (op. 2) REM [ 0 ] - [ 1 ] => (graveyard) [ 1 ]\n// (op. 3) REI (graveyard) [ 1 ] => [ 0 ] - [ 1 ]\n// Then, we undo operation 1:\n// REM [ 1 ] - [ 2 ] => (graveyard) [ 0 ] is reversed to REI (graveyard) [ 0 ] => [ 1 ] - [ 2 ] then,\n// is transformed by (op. 2) REM [ 0 ] - [ 1 ] => (graveyard) [ 1 ] and becomes REI (graveyard) [ 0 ] => [ 0 ] - [ 1 ] then,\n// is transformed by (op. 3) REI (graveyard) [ 1 ] => [ 0 ] - [ 1 ] and we have a conflict because both operations\n// insert at the same position, but thanks to keeping the context, we know that in this case, the transformed operation should\n// insert the node after operation 3.\n//\n// Keep in mind, that `context.insertBefore` may be either `Boolean` or `undefined`. If it is `Boolean` then the order is\n// known (deltas are related and `a` should insert nodes before or after `b`). However, if deltas were not related,\n// `context.isBefore` is `undefined` and other factors will be taken into consideration when resolving the order\n// (this, however, happens in operational transformation algorithms).\n//\n// This affects both `MoveOperation` (and its derivatives) and `InsertOperation`.\nfunction _setInsertBeforeContext( a, b, context ) {\n\t// If `b` is a delta that undoes other delta...\n\tconst originalDelta = context.originalDelta.get( b );\n\n\tif ( context.document.history.isUndoingDelta( originalDelta ) ) {\n\t\t// Get the undone delta...\n\t\tconst undoneDelta = context.document.history.getUndoneDelta( originalDelta );\n\t\t// Get a map with deltas related to `a` delta...\n\t\tconst aWasAffectedBy = context.wasAffected.get( a );\n\t\t// And check if the undone delta is related with delta `a`.\n\t\tconst affected = aWasAffectedBy.get( undoneDelta );\n\n\t\tif ( affected !== undefined ) {\n\t\t\t// If deltas are related, set `context.insertBefore` basing on whether `a` was affected by the undone delta.\n\t\t\tcontext.insertBefore = affected;\n\t\t}\n\t}\n}\n\n// Sets `context.forceNotSticky` basing on `context.document` history for transformation by `b` delta.\n//\n// `MoveOperation` may be \"sticky\" which means, that anything that was inserted at the boundary of moved range, should\n// also be moved. This is particularly helpful for actions like splitting or merging a node. However, this behavior\n// sometimes leads to an error, for example in undo.\n//\n// Simply saying, if delta is going to be transformed by delta `b`, stickiness should not be taken into consideration\n// if delta `b` was already undone or if delta `b` is an undoing delta.\n//\n// This affects `MoveOperation` (and its derivatives).\nfunction _setForceNotSticky( b, context ) {\n\tconst originalDelta = context.originalDelta.get( b );\n\tconst history = context.document.history;\n\n\tcontext.forceNotSticky = history.isUndoneDelta( originalDelta ) || history.isUndoingDelta( originalDelta );\n}\n\n// Sets `context.forceWeakRemove` basing on `context.document` history for transformation by `b` delta.\n//\n// When additional context is not used, default `MoveOperation` x `RemoveOperation` transformation\n// always treats `RemoveOperation` as a stronger one, no matter how `context.isStrong` is set. It is like this\n// to provide better results when transformations happen.\n//\n// This, however, works fine only when additional context is not used.\n//\n// When additional context is used, we need a better way to decide whether `RemoveOperation` is \"dominating\" (or in other\n// words, whether nodes removed by given operation should stay in graveyard if other operation wants to move them).\n//\n// The answer to this is easy: if `RemoveOperation` has been already undone, we are not forcing given nodes to stay\n// in graveyard. In such scenario, we set `context.forceWeakRemove` to `true`. However, if the `RemoveOperation` has\n// not been undone, we set `context.forceWeakRemove` to `false` because we want the operation to be \"dominating\".\nfunction _setForceWeakRemove( b, context ) {\n\tconst history = context.document.history;\n\tconst originalB = context.originalDelta.get( b );\n\n\t// If `b` delta has not been undone yet, forceWeakRemove should be `false`.\n\t// It should be `true`, in any other case, if additional context is used.\n\tcontext.forceWeakRemove = history.isUndoneDelta( originalB );\n}\n\n// Sets `context.wasAffected` which holds context information about how transformed deltas are related. `context.wasAffected`\n// is used by `_setInsertBeforeContext` helper function.\nfunction _setWasAffected( a, b, context ) {\n\tif ( !context.wasAffected.get( a ) ) {\n\t\t// Create a new map with relations for `a` delta.\n\t\tcontext.wasAffected.set( a, new Map() );\n\t}\n\n\tconst originalDelta = context.originalDelta.get( b );\n\tlet wasAffected = !!context.wasAffected.get( a ).get( originalDelta );\n\n\t// Cross-check all operations from both deltas...\n\tfor ( const opA of a.operations ) {\n\t\tfor ( const opB of b.operations ) {\n\t\t\tif ( opA instanceof MoveOperation && opB instanceof MoveOperation ) {\n\t\t\t\tif ( _isOperationAffected( opA, opB ) ) {\n\t\t\t\t\t// If any of them are move operations that affect each other, set the relation accordingly.\n\t\t\t\t\twasAffected = true;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Break both loops if affecting pair has been found.\n\t\tif ( wasAffected ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tcontext.wasAffected.get( a ).set( originalDelta, wasAffected );\n}\n\n// Checks whether `opA` is affected by `opB`. It is assumed that both operations are `MoveOperation`.\n// Operation is affected only if the other operation's source range is before that operation's source range.\nfunction _isOperationAffected( opA, opB ) {\n\tconst target = opA.targetPosition;\n\tconst source = opB.sourcePosition;\n\n\tconst cmpResult = compareArrays( source.getParentPath(), target.getParentPath() );\n\n\tif ( target.root != source.root ) {\n\t\treturn false;\n\t}\n\n\treturn cmpResult == 'same' && source.offset < target.offset;\n}\n\n// Updates `context` object after delta by delta transformation is done.\n//\n// This means two things:\n// 1. Some information are removed from context (those that apply only to the transformation that just happened).\n// 2. `context.wasAffected` is updated because `oldDelta` has been transformed to one or many `newDeltas` and we\n// need to update entries in `context.wasAffected`. Basically, anything that was in `context.wasAffected` under\n// `oldDelta` key should be rewritten to `newDeltas`. This way in next transformation steps, `newDeltas` \"remember\"\n// the context of `oldDelta`.\nfunction _updateContext( oldDelta, newDeltas, context ) {\n\tdelete context.insertBefore;\n\tdelete context.forceNotSticky;\n\tdelete context.forceWeakRemove;\n\n\tconst wasAffected = context.wasAffected.get( oldDelta );\n\n\tcontext.wasAffected.delete( oldDelta );\n\n\tfor ( const delta of newDeltas ) {\n\t\tcontext.wasAffected.set( delta, new Map( wasAffected ) );\n\t}\n}\n\n// Takes base delta class (`DeltaClass`) and a set of `operations` that are transformation results and creates\n// one or more deltas, acknowledging that the result is a transformation of a delta that is of `DeltaClass`.\n//\n// The normalization ensures that each delta has it's \"normal\" state, that is, for example, `MoveDelta` has\n// just one `MoveOperation`, `SplitDelta` has just two operations of which first is `InsertOperation` and second\n// is `MoveOperation` or `NoOperation`, etc.\nfunction getNormalizedDeltas( DeltaClass, operations ) {\n\tlet deltas = [];\n\tlet delta = null;\n\tlet attributeOperationIndex;\n\n\tswitch ( DeltaClass ) {\n\t\tcase MoveDelta:\n\t\tcase RemoveDelta:\n\t\t\t// Normal MoveDelta has just one MoveOperation.\n\t\t\t// Take all operations and create MoveDelta for each of them.\n\t\t\tfor ( const o of operations ) {\n\t\t\t\tif ( o instanceof NoOperation ) {\n\t\t\t\t\t// An operation may be instance of NoOperation and this may be correct.\n\t\t\t\t\t// If that's the case, do not create a MoveDelta with singular NoOperation.\n\t\t\t\t\t// Create \"no delta\" instead, that is Delta instance with NoOperation.\n\t\t\t\t\tdelta = new Delta();\n\t\t\t\t} else {\n\t\t\t\t\tif ( o instanceof RemoveOperation ) {\n\t\t\t\t\t\tdelta = new RemoveDelta();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdelta = new MoveDelta();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdelta.addOperation( o );\n\t\t\t\tdeltas.push( delta );\n\t\t\t}\n\n\t\t\t// Return all created MoveDeltas.\n\t\t\treturn deltas;\n\t\tcase SplitDelta:\n\t\tcase WrapDelta:\n\t\t\t// Normal SplitDelta and WrapDelta have two operations: first is InsertOperation and second is MoveOperation.\n\t\t\t// The MoveOperation may be split into multiple MoveOperations.\n\t\t\t// If that's the case, convert additional MoveOperations into MoveDeltas.\n\t\t\t// First, create normal SplitDelta or WrapDelta, using first two operations.\n\t\t\tdelta = new DeltaClass();\n\t\t\tdelta.addOperation( operations[ 0 ] );\n\t\t\tdelta.addOperation( operations[ 1 ] );\n\t\t\t// Then, take all but last two operations and use them to create normalized MoveDeltas.\n\t\t\tdeltas = getNormalizedDeltas( MoveDelta, operations.slice( 2 ) );\n\n\t\t\t// Return all deltas as one array, in proper order.\n\t\t\treturn [ delta ].concat( deltas );\n\t\tcase MergeDelta:\n\t\tcase UnwrapDelta:\n\t\t\t// Normal MergeDelta and UnwrapDelta have two operations: first is MoveOperation and second is RemoveOperation.\n\t\t\t// The MoveOperation may be split into multiple MoveOperations.\n\t\t\t// If that's the case, convert additional MoveOperations into MoveDeltas.\n\t\t\t// Take all but last two operations and use them to create normalized MoveDeltas.\n\t\t\tdeltas = getNormalizedDeltas( MoveDelta, operations.slice( 0, -2 ) );\n\t\t\t// Then, create normal MergeDelta or UnwrapDelta, using last two operations.\n\t\t\tdelta = new DeltaClass();\n\t\t\tdelta.addOperation( operations[ operations.length - 2 ] );\n\t\t\tdelta.addOperation( operations[ operations.length - 1 ] );\n\n\t\t\t// Return all deltas as one array, in proper order.\n\t\t\treturn deltas.concat( delta );\n\t\tcase RenameDelta:\n\t\t\t// RenameDelta may become a \"no delta\" if it's only operation is transformed to NoOperation.\n\t\t\t// This may happen when RenameOperation is transformed by RenameOperation.\n\t\t\t// Keep in mind that RenameDelta always have just one operation.\n\t\t\tif ( operations[ 0 ] instanceof NoOperation ) {\n\t\t\t\tdelta = new Delta();\n\t\t\t} else {\n\t\t\t\tdelta = new RenameDelta();\n\t\t\t}\n\n\t\t\tdelta.addOperation( operations[ 0 ] );\n\n\t\t\treturn [ delta ];\n\t\tcase AttributeDelta:\n\t\t\t// AttributeDelta is allowed to have multiple AttributeOperations and also NoOperations but\n\t\t\t// the first operation has to be an AttributeOperation as it is used as a reference for deltas properties.\n\t\t\t// Keep in mind that we cannot simply remove NoOperations cause that would mess up base versions.\n\t\t\t// Find an index of first operation that is not a NoOperation.\n\t\t\tfor ( attributeOperationIndex = 0; attributeOperationIndex < operations.length; attributeOperationIndex++ ) {\n\t\t\t\tif ( !( operations[ attributeOperationIndex ] instanceof NoOperation ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// No AttributeOperations has been found. Convert AttributeDelta to \"no delta\".\n\t\t\tif ( attributeOperationIndex == operations.length ) {\n\t\t\t\tdelta = new Delta();\n\t\t\t}\n\t\t\t// AttributeOperation found.\n\t\t\telse {\n\t\t\t\tdelta = new AttributeDelta();\n\n\t\t\t\t// AttributeOperation wasn't the first operation.\n\t\t\t\tif ( attributeOperationIndex != 0 ) {\n\t\t\t\t\t// Move AttributeOperation to the beginning.\n\t\t\t\t\toperations.unshift( operations.splice( attributeOperationIndex, 1 )[ 0 ] );\n\t\t\t\t\t// No need to update base versions - they are updated at the end of transformation algorithm anyway.\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add all operations to the delta (even if it is just a couple of NoOperations we have to keep them all).\n\t\t\tfor ( const o of operations ) {\n\t\t\t\tdelta.addOperation( o );\n\t\t\t}\n\n\t\t\treturn [ delta ];\n\t\tdefault:\n\t\t\t// For all other deltas no normalization is needed.\n\t\t\tdelta = new DeltaClass();\n\n\t\t\tfor ( const o of operations ) {\n\t\t\t\tdelta.addOperation( o );\n\t\t\t}\n\n\t\t\treturn [ delta ];\n\t}\n}\n\n/**\n * Object containing values and flags describing context of a transformation.\n *\n * @typedef {Object} module:engine/model/delta/transform~transformationContext\n * @property {Boolean} useAdditionalContext Whether additional context should be evaluated and used during transformations.\n * @property {Boolean} isStrong Whether transformed deltas are more (`true`) or less (`false`) important than deltas to transform by.\n * @property {module:engine/model/document~Document} [document] Model document which is a context for transformations.\n * Available only if `useAdditionalContext` is `true`.\n * @property {Boolean|undefined} forceWeakRemove Whether {@link module:engine/model/operation/removeoperation~RemoveOperation}\n * should be always more important than other operations. Available only if `useAdditionalContext` is `true`.\n * @property {Boolean|undefined} insertBefore Used when transforming {@link module:engine/model/operation/moveoperation~MoveOperation}s\n * If two `MoveOperation`s target to the same position, `insertBefore` is used to resolve such conflict. This flag\n * is set and used internally by transformation algorithms. Available only if `useAdditionalContext` is `true`.\n * @property {Boolean|undefined} forceNotSticky Used when transforming\n * {@link module:engine/model/operation/moveoperation~MoveOperation#isSticky sticky MoveOperation}. If set to `true`,\n * `isSticky` flag is discarded during transformations. This flag is set and used internally by transformation algorithms.\n * Available only if `useAdditionalContext` is `true`.\n * @property {Map|undefined} wasAffected Used to evaluate `insertBefore` flag. This map is set and used internally by\n * transformation algorithms. Available only if `useAdditionalContext` is `true`.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/transform.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/markerdelta\n */\n\nimport Delta from './delta';\nimport DeltaFactory from './deltafactory';\nimport { register } from '../batch';\nimport MarkerOperation from '../operation/markeroperation';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#setMarker Batch#setMarker}\n * and {@link module:engine/model/batch~Batch#removeMarker Batch#removeMarker} methods use the `MarkerDelta` class which inherits\n * from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class MarkerDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'marker';\n\t}\n\n\t/**\n\t * A class that will be used when creating reversed delta.\n\t *\n\t * @private\n\t * @type {Function}\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn MarkerDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.MarkerDelta';\n\t}\n}\n\n/**\n * Adds or updates {@link module:engine/model/markercollection~Marker marker} with given name to given `range`.\n *\n * If passed name is a name of already existing marker (or {@link module:engine/model/markercollection~Marker Marker} instance\n * is passed), `range` parameter may be omitted. In this case marker will not be updated in\n * {@link module:engine/model/document~Document#markers document marker collection}. However the marker will be added to\n * the document history. This may be important for other features, like undo. From document history point of view, it will\n * look like the marker was created and added to the document at the moment when it is set using this method.\n *\n * This is useful if the marker is created before it can be added to document history (e.g. a feature creating the marker\n * is waiting for additional data, etc.). In this case, the marker may be first created directly through\n * {@link module:engine/model/markercollection~MarkerCollection MarkerCollection API} and only later added using `Batch` API.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#setMarker\n * @param {module:engine/model/markercollection~Marker|String} markerOrName Marker or marker name to add or update.\n * @param {module:engine/model/range~Range} [newRange] Marker range.\n */\nregister( 'setMarker', function( markerOrName, newRange ) {\n\tconst name = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n\tconst currentMarker = this.document.markers.get( name );\n\n\tif ( !newRange && !currentMarker ) {\n\t\t/**\n\t\t * Range parameter is required when adding a new marker.\n\t\t *\n\t\t * @error batch-setMarker-no-range\n\t\t */\n\t\tthrow new CKEditorError( 'batch-setMarker-no-range: Range parameter is required when adding a new marker.' );\n\t}\n\n\tconst currentRange = currentMarker ? currentMarker.getRange() : null;\n\n\tif ( !newRange ) {\n\t\t// If `newRange` is not given, treat this as synchronizing existing marker.\n\t\t// Create `MarkerOperation` with `oldRange` set to `null`, so reverse operation will remove the marker.\n\t\taddOperation( this, name, null, currentRange );\n\t} else {\n\t\t// Just change marker range.\n\t\taddOperation( this, name, currentRange, newRange );\n\t}\n\n\treturn this;\n} );\n\n/**\n * Removes given {@link module:engine/model/markercollection~Marker marker} or marker with given name.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#removeMarker\n * @param {module:engine/model/markercollection~Marker|String} markerOrName Marker or marker name to remove.\n */\nregister( 'removeMarker', function( markerOrName ) {\n\tconst name = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n\n\tif ( !this.document.markers.has( name ) ) {\n\t\t/**\n\t\t * Trying to remove marker which does not exist.\n\t\t *\n\t\t * @error batch-removeMarker-no-marker\n\t\t */\n\t\tthrow new CKEditorError( 'batch-removeMarker-no-marker: Trying to remove marker which does not exist.' );\n\t}\n\n\tconst oldRange = this.document.markers.get( name ).getRange();\n\n\taddOperation( this, name, oldRange, null );\n\n\treturn this;\n} );\n\nfunction addOperation( batch, name, oldRange, newRange ) {\n\tconst doc = batch.document;\n\tconst delta = new MarkerDelta();\n\n\tconst operation = new MarkerOperation( name, oldRange, newRange, doc.markers, doc.version );\n\n\tbatch.addDelta( delta );\n\tdelta.addOperation( operation );\n\tdoc.applyOperation( operation );\n}\n\nDeltaFactory.register( MarkerDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/markerdelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/basic-transformations\n */\n\nimport deltaTransform from './transform';\nconst addTransformationCase = deltaTransform.addTransformationCase;\nconst defaultTransform = deltaTransform.defaultTransform;\n\nimport Range from '../range';\nimport Position from '../position';\n\nimport NoOperation from '../operation/nooperation';\nimport AttributeOperation from '../operation/attributeoperation';\nimport InsertOperation from '../operation/insertoperation';\nimport ReinsertOperation from '../operation/reinsertoperation';\n\nimport Delta from './delta';\nimport AttributeDelta from './attributedelta';\nimport InsertDelta from './insertdelta';\nimport MarkerDelta from './markerdelta';\nimport MergeDelta from './mergedelta';\nimport MoveDelta from './movedelta';\nimport SplitDelta from './splitdelta';\nimport WeakInsertDelta from './weakinsertdelta';\nimport WrapDelta from './wrapdelta';\nimport UnwrapDelta from './unwrapdelta';\nimport RenameDelta from './renamedelta';\nimport RemoveDelta from './removedelta';\n\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\n\n// Provide transformations for default deltas.\n\n// Add special case for AttributeDelta x WeakInsertDelta transformation.\naddTransformationCase( AttributeDelta, WeakInsertDelta, ( a, b, context ) => {\n\t// If nodes are weak-inserted into attribute delta range, we need to apply changes from attribute delta on them.\n\t// So first we do the normal transformation and if this special cases happens, we will add an extra delta.\n\tconst deltas = defaultTransform( a, b, context );\n\n\tif ( a.range.containsPosition( b.position ) ) {\n\t\tdeltas.push( _getComplementaryAttrDelta( b, a ) );\n\t}\n\n\treturn deltas;\n} );\n\n// Add special case for AttributeDelta x SplitDelta transformation.\naddTransformationCase( AttributeDelta, SplitDelta, ( a, b, context ) => {\n\t// Do not apply special transformation case if `SplitDelta` has `NoOperation` as the second operation.\n\tif ( !b.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\tconst undoMode = context.undoMode;\n\tconst splitPosition = new Position( b.position.root, b.position.path.slice( 0, -1 ) );\n\n\tconst deltas = defaultTransform( a, b, context );\n\n\t// Special case applies only if undo is not a context and only if `SplitDelta` has `InsertOperation` (not `ReinsertOperation`).\n\tif ( undoMode || !( b._cloneOperation instanceof InsertOperation ) ) {\n\t\treturn deltas;\n\t}\n\n\tfor ( const operation of a.operations ) {\n\t\t// If a node that has been split has it's attribute updated, we should also update attribute of\n\t\t// the node created during splitting.\n\t\tif ( operation.range.containsPosition( splitPosition ) || operation.range.start.isEqual( splitPosition ) ) {\n\t\t\tconst additionalAttributeDelta = new AttributeDelta();\n\n\t\t\tconst rangeStart = splitPosition.getShiftedBy( 1 );\n\t\t\tconst rangeEnd = Position.createFromPosition( rangeStart );\n\t\t\trangeEnd.path.push( 0 );\n\n\t\t\tconst oldValue = b._cloneOperation.nodes.getNode( 0 ).getAttribute( operation.key );\n\n\t\t\tadditionalAttributeDelta.addOperation( new AttributeOperation(\n\t\t\t\tnew Range( rangeStart, rangeEnd ),\n\t\t\t\toperation.key,\n\t\t\t\toldValue === undefined ? null : oldValue,\n\t\t\t\toperation.newValue,\n\t\t\t\t0\n\t\t\t) );\n\n\t\t\tdeltas.push( additionalAttributeDelta );\n\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn deltas;\n} );\n\n// Add special case for InsertDelta x MergeDelta transformation.\naddTransformationCase( InsertDelta, MergeDelta, ( a, b, context ) => {\n\t// Do not apply special transformation case if `MergeDelta` has `NoOperation` as the second operation.\n\tif ( !b.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\tconst undoMode = context.undoMode;\n\n\t// If insert is applied at the same position where merge happened, we reverse the merge (we treat it like it\n\t// didn't happen) and then apply the original insert operation. This is \"mirrored\" in MergeDelta x InsertDelta\n\t// transformation below, where we simply do not apply MergeDelta.\n\tif ( !undoMode && a.position.isEqual( b.position ) ) {\n\t\treturn [\n\t\t\tb.getReversed(),\n\t\t\ta.clone()\n\t\t];\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\nfunction transformMarkerDelta( a, b ) {\n\tconst transformedDelta = a.clone();\n\tconst transformedOp = transformedDelta.operations[ 0 ];\n\n\tif ( transformedOp.oldRange ) {\n\t\ttransformedOp.oldRange = transformedOp.oldRange.getTransformedByDelta( b )[ 0 ];\n\t}\n\n\tif ( transformedOp.newRange ) {\n\t\ttransformedOp.newRange = transformedOp.newRange.getTransformedByDelta( b )[ 0 ];\n\t}\n\n\treturn [ transformedDelta ];\n}\n\naddTransformationCase( MarkerDelta, SplitDelta, transformMarkerDelta );\naddTransformationCase( MarkerDelta, MergeDelta, transformMarkerDelta );\naddTransformationCase( MarkerDelta, WrapDelta, transformMarkerDelta );\naddTransformationCase( MarkerDelta, UnwrapDelta, transformMarkerDelta );\naddTransformationCase( MarkerDelta, MoveDelta, transformMarkerDelta );\naddTransformationCase( MarkerDelta, RenameDelta, transformMarkerDelta );\n\n// Add special case for MoveDelta x MergeDelta transformation.\naddTransformationCase( MoveDelta, MergeDelta, ( a, b, context ) => {\n\tconst undoMode = context.undoMode;\n\n\t// Do not apply special transformation case in undo mode or if `MergeDelta` has `NoOperation` as the second operation.\n\tif ( undoMode || !b.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\t// If move delta is supposed to move a node that has been merged, we reverse the merge (we treat it like it\n\t// didn't happen) and then apply the original move operation. This is \"mirrored\" in MergeDelta x MoveDelta\n\t// transformation below, where we simply do not apply MergeDelta.\n\tconst operateInSameParent =\n\t\ta.sourcePosition.root == b.position.root &&\n\t\tcompareArrays( a.sourcePosition.getParentPath(), b.position.getParentPath() ) === 'same';\n\n\tconst mergeInsideMoveRange = a.sourcePosition.offset <= b.position.offset && a.sourcePosition.offset + a.howMany > b.position.offset;\n\n\tif ( operateInSameParent && mergeInsideMoveRange ) {\n\t\treturn [\n\t\t\tb.getReversed(),\n\t\t\ta.clone()\n\t\t];\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\n// Add special case for MergeDelta x InsertDelta transformation.\naddTransformationCase( MergeDelta, InsertDelta, ( a, b, context ) => {\n\t// Do not apply special transformation case if `MergeDelta` has `NoOperation` as the second operation.\n\tif ( !a.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\tconst undoMode = context.undoMode;\n\n\t// If merge is applied at the same position where we inserted a range of nodes we cancel the merge as it's results\n\t// may be unexpected and very weird. Even if we do some \"magic\" we don't know what really are users' expectations.\n\tif ( !undoMode && a.position.isEqual( b.position ) ) {\n\t\treturn [ noDelta() ];\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\n// Add special case for MergeDelta x MoveDelta transformation.\naddTransformationCase( MergeDelta, MoveDelta, ( a, b, context ) => {\n\tconst undoMode = context.undoMode;\n\n\t// Do not apply special transformation case in undo mode or if `MergeDelta` has `NoOperation` as the second operation.\n\tif ( undoMode || !a.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\t// If merge is applied at the position between moved nodes we cancel the merge as it's results may be unexpected and\n\t// very weird. Even if we do some \"magic\" we don't know what really are users' expectations.\n\tconst operateInSameParent =\n\t\ta.position.root == b.sourcePosition.root &&\n\t\tcompareArrays( a.position.getParentPath(), b.sourcePosition.getParentPath() ) === 'same';\n\n\tconst mergeInsideMoveRange = b.sourcePosition.offset <= a.position.offset && b.sourcePosition.offset + b.howMany > a.position.offset;\n\n\tif ( operateInSameParent && mergeInsideMoveRange ) {\n\t\treturn [ noDelta() ];\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\naddTransformationCase( SplitDelta, SplitDelta, ( a, b, context ) => {\n\tconst undoMode = context.undoMode;\n\n\t// Do not apply special transformation case if transformation is in undo mode.\n\tif ( undoMode ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\t// Do not apply special transformation case if `SplitDelta` has `NoOperation` as the second operation.\n\tif ( !a.position || !b.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\tconst pathA = a.position.getParentPath();\n\tconst pathB = b.position.getParentPath();\n\n\t// The special case is for splits inside the same parent.\n\tif ( a.position.root == b.position.root && compareArrays( pathA, pathB ) == 'same' ) {\n\t\ta = a.clone();\n\n\t\tif ( a.position.offset < b.position.offset || ( a.position.offset == b.position.offset && context.isStrong ) ) {\n\t\t\t// If both first operations are `ReinsertOperation`s, we might need to transform `a._cloneOperation`,\n\t\t\t// so it will take correct node from graveyard.\n\t\t\tif (\n\t\t\t\ta._cloneOperation instanceof ReinsertOperation && b._cloneOperation instanceof ReinsertOperation &&\n\t\t\t\ta._cloneOperation.sourcePosition.offset > b._cloneOperation.sourcePosition.offset\n\t\t\t) {\n\t\t\t\ta._cloneOperation.sourcePosition.offset--;\n\t\t\t}\n\n\t\t\t// `a` splits closer or at same offset.\n\t\t\t// Change how many nodes are moved. Do not move nodes that were moved by delta `b`.\n\t\t\tconst aRange = Range.createFromPositionAndShift( a.position, a._moveOperation.howMany );\n\t\t\tconst bRange = Range.createFromPositionAndShift( b.position, b._moveOperation.howMany );\n\n\t\t\tconst diff = aRange.getDifference( bRange );\n\n\t\t\tlet newHowMany = 0;\n\n\t\t\tfor ( const range of diff ) {\n\t\t\t\tnewHowMany += range.end.offset - range.start.offset;\n\t\t\t}\n\n\t\t\tif ( newHowMany === 0 ) {\n\t\t\t\ta.operations.pop(); // Remove last operation (`MoveOperation`).\n\t\t\t\ta.addOperation( new NoOperation( a.operations[ 0 ].baseVersion + 1 ) ); // Add `NoOperation` instead.\n\t\t\t} else {\n\t\t\t\ta.operations[ 1 ].howMany = newHowMany;\n\t\t\t}\n\n\t\t\treturn [ a ];\n\t\t} else {\n\t\t\t// `a` splits further.\n\t\t\t// This is more complicated case, thankfully we can solve it using default transformation and setting proper context.\n\t\t\tconst newContext = Object.assign( {}, context );\n\t\t\tnewContext.isStrong = true;\n\t\t\tnewContext.insertBefore = true;\n\n\t\t\treturn defaultTransform( a, b, newContext );\n\t\t}\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\n// Add special case for SplitDelta x UnwrapDelta transformation.\naddTransformationCase( SplitDelta, UnwrapDelta, ( a, b, context ) => {\n\t// Do not apply special transformation case if `SplitDelta` has `NoOperation` as the second operation.\n\tif ( !a.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\t// If incoming split delta tries to split a node that just got unwrapped, there is actually nothing to split,\n\t// so we discard that delta.\n\tif ( a.position.root == b.position.root && compareArrays( b.position.path, a.position.getParentPath() ) === 'same' ) {\n\t\treturn [ noDelta() ];\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\n// Add special case for SplitDelta x WrapDelta transformation.\naddTransformationCase( SplitDelta, WrapDelta, ( a, b, context ) => {\n\t// Do not apply special transformation case if `SplitDelta` has `NoOperation` as the second operation.\n\tif ( !a.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\t// If split is applied at the position between wrapped nodes, we cancel the split as it's results may be unexpected and\n\t// very weird. Even if we do some \"magic\" we don't know what really are users' expectations.\n\n\tconst sameRoot = a.position.root == b.range.start.root;\n\tconst operateInSameParent = sameRoot && compareArrays( a.position.getParentPath(), b.range.start.getParentPath() ) === 'same';\n\tconst splitInsideWrapRange = b.range.start.offset < a.position.offset && b.range.end.offset >= a.position.offset;\n\n\tif ( operateInSameParent && splitInsideWrapRange ) {\n\t\treturn [ noDelta() ];\n\t} else if ( sameRoot && compareArrays( a.position.getParentPath(), b.range.end.getShiftedBy( -1 ).path ) === 'same' ) {\n\t\t// Split position is directly inside the last node from wrap range.\n\t\t// If that's the case, we manually change split delta so it will \"target\" inside the wrapping element.\n\t\t// By doing so we will be inserting split node right to the original node which feels natural and is a good UX.\n\t\tconst delta = a.clone();\n\n\t\t// 1. Fix insert operation position.\n\t\t// Node to split is the last children of the wrapping element.\n\t\t// Wrapping element is the element inserted by WrapDelta (re)insert operation.\n\t\t// It is inserted after the wrapped range, but the wrapped range will be moved inside it.\n\t\t// Having this in mind, it is correct to use wrapped range start position as the position before wrapping element.\n\t\tconst splitNodePos = Position.createFromPosition( b.range.start );\n\t\t// Now, `splitNodePos` points before wrapping element.\n\t\t// To get a position before last children of that element, we expand position's `path` member by proper offset.\n\t\tsplitNodePos.path.push( b.howMany - 1 );\n\n\t\t// SplitDelta insert operation position should be right after the node we split.\n\t\tconst insertPos = splitNodePos.getShiftedBy( 1 );\n\t\tdelta._cloneOperation.position = insertPos;\n\n\t\t// 2. Fix move operation source position.\n\t\t// Nodes moved by SplitDelta will be moved from new position, modified by WrapDelta.\n\t\t// To obtain that new position, `splitNodePos` will be used, as this is the node we are extracting children from.\n\t\tconst sourcePos = Position.createFromPosition( splitNodePos );\n\t\t// Nothing changed inside split node so it is correct to use the original split position offset.\n\t\tsourcePos.path.push( a.position.offset );\n\t\tdelta._moveOperation.sourcePosition = sourcePos;\n\n\t\t// 3. Fix move operation target position.\n\t\t// SplitDelta move operation target position should be inside the node inserted by operation above.\n\t\t// Since the node is empty, we will insert at offset 0.\n\t\tconst targetPos = Position.createFromPosition( insertPos );\n\t\ttargetPos.path.push( 0 );\n\t\tdelta._moveOperation.targetPosition = targetPos;\n\n\t\treturn [ delta ];\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\n// Add special case for SplitDelta x WrapDelta transformation.\naddTransformationCase( SplitDelta, AttributeDelta, ( a, b, context ) => {\n\t// Do not apply special transformation case if `SplitDelta` has `NoOperation` as the second operation.\n\tif ( !a.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\ta = a.clone();\n\n\tconst undoMode = context.undoMode;\n\tconst splitPosition = new Position( a.position.root, a.position.path.slice( 0, -1 ) );\n\n\t// Special case applies only if undo is not a context and only if `SplitDelta` has `InsertOperation` (not `ReinsertOperation`).\n\tif ( undoMode || !( a._cloneOperation instanceof InsertOperation ) ) {\n\t\treturn [ a ];\n\t}\n\n\t// If element to split had it's attribute changed, we have to reflect this change in an element\n\t// that is in SplitDelta's InsertOperation.\n\tfor ( const operation of b.operations ) {\n\t\tif ( operation.range.containsPosition( splitPosition ) || operation.range.start.isEqual( splitPosition ) ) {\n\t\t\tif ( operation.newValue !== null ) {\n\t\t\t\ta._cloneOperation.nodes.getNode( 0 ).setAttribute( operation.key, operation.newValue );\n\t\t\t} else {\n\t\t\t\ta._cloneOperation.nodes.getNode( 0 ).removeAttribute( operation.key );\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn [ a ];\n} );\n\n// Add special case for UnwrapDelta x SplitDelta transformation.\naddTransformationCase( UnwrapDelta, SplitDelta, ( a, b, context ) => {\n\t// Do not apply special transformation case if `SplitDelta` has `NoOperation` as the second operation.\n\tif ( !b.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\t// If incoming unwrap delta tries to unwrap node that got split we should unwrap the original node and the split copy.\n\t// This can be achieved either by reverting split and applying unwrap to singular node, or creating additional unwrap delta.\n\tif ( a.position.root == b.position.root && compareArrays( a.position.path, b.position.getParentPath() ) === 'same' ) {\n\t\treturn [\n\t\t\tb.getReversed(),\n\t\t\ta.clone()\n\t\t];\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\n// Add special case for WeakInsertDelta x AttributeDelta transformation.\naddTransformationCase( WeakInsertDelta, AttributeDelta, ( a, b ) => {\n\t// If nodes are weak-inserted into attribute delta range, we need to apply changes from attribute delta on them.\n\tconst deltas = [ a.clone() ];\n\n\tif ( b.range.containsPosition( a.position ) ) {\n\t\tdeltas.push( _getComplementaryAttrDelta( a, b ) );\n\t}\n\n\treturn deltas;\n} );\n\n// Add special case for WrapDelta x SplitDelta transformation.\naddTransformationCase( WrapDelta, SplitDelta, ( a, b, context ) => {\n\t// Do not apply special transformation case if `SplitDelta` has `NoOperation` as the second operation.\n\tif ( !b.position ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\t// If incoming wrap delta tries to wrap range that contains split position, we have to cancel the split and apply\n\t// the wrap. Since split was already applied, we have to revert it.\n\tconst sameRoot = a.range.start.root == b.position.root;\n\tconst operateInSameParent = sameRoot && compareArrays( a.range.start.getParentPath(), b.position.getParentPath() ) === 'same';\n\tconst splitInsideWrapRange = a.range.start.offset < b.position.offset && a.range.end.offset >= b.position.offset;\n\n\tif ( operateInSameParent && splitInsideWrapRange ) {\n\t\treturn [\n\t\t\tb.getReversed(),\n\t\t\ta.clone()\n\t\t];\n\t} else if ( sameRoot && compareArrays( b.position.getParentPath(), a.range.end.getShiftedBy( -1 ).path ) === 'same' ) {\n\t\tconst delta = a.clone();\n\n\t\t// Move wrapping element insert position one node further so it is after the split node insertion.\n\t\tdelta._insertOperation.position.offset++;\n\n\t\t// Include the split node copy.\n\t\tdelta._moveOperation.howMany++;\n\n\t\t// Change the path to wrapping element in move operation.\n\t\tdelta._moveOperation.targetPosition.path[ delta._moveOperation.targetPosition.path.length - 2 ]++;\n\n\t\treturn [ delta ];\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\n// Add special case for RenameDelta x SplitDelta transformation.\naddTransformationCase( RenameDelta, SplitDelta, ( a, b, context ) => {\n\tconst undoMode = context.undoMode;\n\tconst deltas = defaultTransform( a, b, context );\n\n\t// Special case applies only if undo is not a context and only if `SplitDelta` has `InsertOperation` (not `ReinsertOperation`).\n\tif ( undoMode || !( b._cloneOperation instanceof InsertOperation ) ) {\n\t\treturn deltas;\n\t}\n\n\tconst insertPosition = b._cloneOperation.position.getShiftedBy( -1 );\n\n\tif ( insertPosition && a.operations[ 0 ].position.isEqual( insertPosition ) ) {\n\t\t// If a node that has been split has it's name changed, we should also change name of\n\t\t// the node created during splitting.\n\t\tconst additionalRenameDelta = a.clone();\n\t\tadditionalRenameDelta.operations[ 0 ].position = insertPosition.getShiftedBy( 1 );\n\n\t\tdeltas.push( additionalRenameDelta );\n\t}\n\n\treturn deltas;\n} );\n\n// Add special case for SplitDelta x RenameDelta transformation.\naddTransformationCase( SplitDelta, RenameDelta, ( a, b, context ) => {\n\ta = a.clone();\n\n\tconst undoMode = context.undoMode;\n\n\t// Special case applies only if undo is not a context and only if `SplitDelta` has `InsertOperation` (not `ReinsertOperation`).\n\tif ( undoMode || !( a._cloneOperation instanceof InsertOperation ) ) {\n\t\treturn [ a ];\n\t}\n\n\tconst insertPosition = a._cloneOperation.position.getShiftedBy( -1 );\n\n\t// If element to split had it's name changed, we have to reflect this by creating additional rename operation.\n\tif ( insertPosition && !undoMode && b.operations[ 0 ].position.isEqual( insertPosition ) ) {\n\t\tconst additionalRenameDelta = b.clone();\n\t\tadditionalRenameDelta.operations[ 0 ].position = insertPosition.getShiftedBy( 1 );\n\t\tadditionalRenameDelta.operations[ 0 ].oldName = a._cloneOperation.nodes.getNode( 0 ).name;\n\n\t\treturn [ a, additionalRenameDelta ];\n\t}\n\n\treturn [ a ];\n} );\n\n// Add special case for RemoveDelta x SplitDelta transformation.\naddTransformationCase( RemoveDelta, SplitDelta, ( a, b, context ) => {\n\tconst deltas = defaultTransform( a, b, context );\n\t// The \"clone operation\" may be InsertOperation, ReinsertOperation, MoveOperation or NoOperation.\n\tconst insertPosition = b._cloneOperation.position || b._cloneOperation.targetPosition;\n\n\t// NoOperation.\n\tif ( !insertPosition ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\tconst undoMode = context.undoMode;\n\n\t// Special case applies only if undo is not a context.\n\tif ( undoMode ) {\n\t\treturn deltas;\n\t}\n\n\t// In case if `defaultTransform` returned more than one delta.\n\tfor ( const delta of deltas ) {\n\t\t// \"No delta\" may be returned in some cases.\n\t\tif ( delta instanceof RemoveDelta ) {\n\t\t\tconst operation = delta._moveOperation;\n\t\t\tconst rangeEnd = operation.sourcePosition.getShiftedBy( operation.howMany );\n\n\t\t\tif ( rangeEnd.isEqual( insertPosition ) ) {\n\t\t\t\toperation.howMany += 1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn deltas;\n} );\n\n// Add special case for SplitDelta x RemoveDelta transformation.\naddTransformationCase( SplitDelta, RemoveDelta, ( a, b, context ) => {\n\tconst undoMode = context.undoMode;\n\n\t// Special case applies only if undo is not a context.\n\tif ( undoMode ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\t// This case is very trickily solved.\n\t// Instead of fixing `a` delta, we change `b` delta for a while and fire default transformation with fixed `b` delta.\n\t// Thanks to that fixing `a` delta will be differently (correctly) transformed.\n\t//\n\t// The \"clone operation\" may be InsertOperation, ReinsertOperation, MoveOperation or NoOperation.\n\tconst insertPosition = a._cloneOperation.position || a._cloneOperation.targetPosition;\n\n\t// NoOperation.\n\tif ( !insertPosition ) {\n\t\treturn defaultTransform( a, b, context );\n\t}\n\n\tb = b.clone();\n\tconst operation = b._moveOperation;\n\tconst rangeEnd = operation.sourcePosition.getShiftedBy( operation.howMany );\n\n\tif ( rangeEnd.isEqual( insertPosition ) ) {\n\t\toperation.howMany += 1;\n\t}\n\n\treturn defaultTransform( a, b, context );\n} );\n\n// Helper function for `AttributeDelta` class transformations.\n// Creates an attribute delta that sets attribute from given `attributeDelta` on nodes from given `weakInsertDelta`.\nfunction _getComplementaryAttrDelta( weakInsertDelta, attributeDelta ) {\n\tconst complementaryAttrDelta = new AttributeDelta();\n\tconst nodes = weakInsertDelta.nodes;\n\n\t// At the beginning we store the attribute value from the first node on `weakInsertDelta` node list.\n\tlet val = nodes.getNode( 0 ).getAttribute( attributeDelta.key );\n\n\t// This stores the last index of `weakInsertDelta` node list where the attribute value was different\n\t// than in the previous node. We need it to create separate `AttributeOperation`s for nodes with different attributes.\n\tlet lastOffset = 0;\n\t// Sum of offsets of already processed nodes.\n\tlet offsetSum = nodes.getNode( 0 ).offsetSize;\n\n\tfor ( let i = 1; i < nodes.length; i++ ) {\n\t\tconst node = nodes.getNode( i );\n\t\tconst nodeAttrVal = node.getAttribute( attributeDelta.key );\n\n\t\t// If previous node has different attribute value, we will create an operation to the point before current node.\n\t\t// So all nodes with the same attributes up to this point will be included in one `AttributeOperation`.\n\t\tif ( nodeAttrVal != val ) {\n\t\t\t// New operation is created only when it is needed. If given node already has proper value for this\n\t\t\t// attribute we simply skip it without adding a new operation.\n\t\t\tif ( val != attributeDelta.value ) {\n\t\t\t\taddOperation();\n\t\t\t}\n\n\t\t\tval = nodeAttrVal;\n\t\t\tlastOffset = offsetSum;\n\t\t}\n\n\t\toffsetSum = offsetSum + node.offsetSize;\n\t}\n\n\t// At the end we have to add additional `AttributeOperation` for the last part of node list. If all nodes on the\n\t// node list had same attributes, this will be the only operation added to the delta.\n\taddOperation();\n\n\treturn complementaryAttrDelta;\n\n\tfunction addOperation() {\n\t\tconst range = new Range(\n\t\t\tweakInsertDelta.position.getShiftedBy( lastOffset ),\n\t\t\tweakInsertDelta.position.getShiftedBy( offsetSum )\n\t\t);\n\n\t\tconst attrOperation = new AttributeOperation( range, attributeDelta.key, val, attributeDelta.value, 0 );\n\t\tcomplementaryAttrDelta.addOperation( attrOperation );\n\t}\n}\n\n// This is \"no-op\" delta, it has no type and only no-operation, it basically does nothing.\n// It is used when we don't want to apply changes but still we need to return a delta.\nfunction noDelta() {\n\tconst noDelta = new Delta();\n\n\t// BaseVersion will be fixed later anyway.\n\tnoDelta.addOperation( new NoOperation( 0 ) );\n\n\treturn noDelta;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/basic-transformations.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/rootelement\n */\n\nimport Element from './element';\n\n/**\n * Type of {@link module:engine/model/element~Element} that is a root of a model tree.\n * @extends module:engine/model/element~Element\n */\nexport default class RootElement extends Element {\n\t/**\n\t * Creates root element.\n\t *\n\t * @param {module:engine/model/document~Document} doc Document that is an owner of this root.\n\t * @param {String} name Node name.\n\t * @param {String} [rootName='main'] Unique root name used to identify this root\n\t * element by {@link module:engine/model/document~Document}.\n\t */\n\tconstructor( doc, name, rootName = 'main' ) {\n\t\tsuper( name );\n\n\t\t/**\n\t\t * Document that is an owner of this root.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/document~Document}\n\t\t */\n\t\tthis._doc = doc;\n\n\t\t/**\n\t\t * Unique root name used to identify this root element by {@link module:engine/model/document~Document}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.rootName = rootName;\n\t}\n\n\t/**\n\t * {@link module:engine/model/document~Document Document} that owns this root element.\n\t *\n\t * In contrary, to {@link module:engine/model/node~Node node}, root element always have a `document`.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/document~Document|null}\n\t */\n\tget document() {\n\t\treturn this._doc;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'rootElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'rootElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\t/**\n\t * Converts `RootElement` instance to `String` containing it's name.\n\t *\n\t * @returns {String} `RootElement` instance converted to `String`.\n\t */\n\ttoJSON() {\n\t\treturn this.rootName;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/rootelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/liverange\n */\n\nimport Range from './range';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * `LiveRange` is a type of {@link module:engine/model/range~Range Range}\n * that updates itself as {@link module:engine/model/document~Document document}\n * is changed through operations. It may be used as a bookmark.\n *\n * **Note:** Be very careful when dealing with `LiveRange`. Each `LiveRange` instance bind events that might\n * have to be unbound. Use {@link module:engine/model/liverange~LiveRange#detach detach} whenever you don't need `LiveRange` anymore.\n */\nexport default class LiveRange extends Range {\n\t/**\n\t * Creates a live range.\n\t *\n\t * @see module:engine/model/range~Range\n\t */\n\tconstructor( start, end ) {\n\t\tsuper( start, end );\n\n\t\tbindWithDocument.call( this );\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by `LiveRange`. Use it whenever you don't need `LiveRange` 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\n\t/**\n\t * @see module:engine/model/range~Range.createIn\n\t * @static\n\t * @method module:engine/model/liverange~LiveRange.createIn\n\t * @param {module:engine/model/element~Element} element\n\t * @returns {module:engine/model/liverange~LiveRange}\n\t */\n\n\t/**\n\t * @see module:engine/model/range~Range.createFromPositionAndShift\n\t * @static\n\t * @method module:engine/model/liverange~LiveRange.createFromPositionAndShift\n\t * @param {module:engine/model/position~Position} position\n\t * @param {Number} shift\n\t * @returns {module:engine/model/liverange~LiveRange}\n\t */\n\n\t/**\n\t * @see module:engine/model/range~Range.createFromParentsAndOffsets\n\t * @static\n\t * @method module:engine/model/liverange~LiveRange.createFromParentsAndOffsets\n\t * @param {module:engine/model/element~Element} startElement\n\t * @param {Number} startOffset\n\t * @param {module:engine/model/element~Element} endElement\n\t * @param {Number} endOffset\n\t * @returns {module:engine/model/liverange~LiveRange}\n\t */\n\n\t/**\n\t * @see module:engine/model/range~Range.createFromRange\n\t * @static\n\t * @method module:engine/model/liverange~LiveRange.createFromRange\n\t * @param {module:engine/model/range~Range} range\n\t * @returns {module:engine/model/liverange~LiveRange}\n\t */\n\n\t/**\n\t * Fired when `LiveRange` instance boundaries have changed due to changes in the\n\t * {@link module:engine/model/document~Document document}.\n\t *\n\t * @event change:range\n\t * @param {module:engine/model/range~Range} oldRange Range with start and end position equal to start and end position of this live\n\t * range before it got changed.\n\t * @param {Object} data Object with additional information about the change. Those parameters are passed from\n\t * {@link module:engine/model/document~Document#event:change document change event}.\n\t * @param {String} data.type Change type.\n\t * @param {module:engine/model/batch~Batch} data.batch Batch which changed the live range.\n\t * @param {module:engine/model/range~Range} data.range Range containing the result of applied change.\n\t * @param {module:engine/model/position~Position} data.sourcePosition Source position for move, remove and reinsert change types.\n\t */\n\n\t/**\n\t * Fired when `LiveRange` instance boundaries have not changed after a change in {@link module:engine/model/document~Document document}\n\t * but the change took place inside the range, effectively changing its content.\n\t *\n\t * @event change:content\n\t * @param {module:engine/model/range~Range} range Range with start and end position equal to start and end position of\n\t * change range.\n\t * @param {Object} data Object with additional information about the change. Those parameters are passed from\n\t * {@link module:engine/model/document~Document#event:change document change event}.\n\t * @param {String} data.type Change type.\n\t * @param {module:engine/model/batch~Batch} data.batch Batch which changed the live range.\n\t * @param {module:engine/model/range~Range} data.range Range containing the result of applied change.\n\t * @param {module:engine/model/position~Position} data.sourcePosition Source position for move, remove and reinsert change types.\n\t */\n}\n\n/**\n * Binds this `LiveRange` to the {@link module:engine/model/document~Document document}\n * that owns this range's {@link module:engine/model/range~Range#root root}.\n *\n * @ignore\n * @private\n * @method module:engine/model/liverange~LiveRange#bindWithDocument\n */\nfunction bindWithDocument() {\n\t// Operation types that a range can be transformed by.\n\tconst supportedTypes = new Set( [ 'insert', 'move', 'remove', 'reinsert' ] );\n\n\tthis.listenTo(\n\t\tthis.root.document,\n\t\t'change',\n\t\t( event, type, changes, batch, deltaType ) => {\n\t\t\tif ( supportedTypes.has( type ) ) {\n\t\t\t\ttransform.call( this, type, deltaType, batch, changes.range, changes.sourcePosition );\n\t\t\t}\n\t\t},\n\t\t{ priority: 'high' }\n\t);\n}\n\n/**\n * Updates this range accordingly to the updates applied to the model. Bases on change events.\n *\n * @ignore\n * @private\n * @method transform\n * @param {String} [changeType] Type of change applied to the model document.\n * @param {String} [deltaType] Type of delta which introduced the change.\n * @param {module:engine/model/batch~Batch} batch Batch which changes the live range.\n * @param {module:engine/model/range~Range} targetRange Range containing the result of applied change.\n * @param {module:engine/model/position~Position} [sourcePosition] Source position for move, remove and reinsert change types.\n */\nfunction transform( changeType, deltaType, batch, targetRange, sourcePosition ) {\n\tconst howMany = targetRange.end.offset - targetRange.start.offset;\n\tlet targetPosition = targetRange.start;\n\n\tif ( changeType == 'move' || changeType == 'remove' || changeType == 'reinsert' ) {\n\t\t// Range._getTransformedByDocumentChange is expecting `targetPosition` to be \"before\" move\n\t\t// (before transformation). `targetRange.start` is already after the move happened.\n\t\t// We have to revert `targetPosition` to the state before the move.\n\t\ttargetPosition = targetPosition._getTransformedByInsertion( sourcePosition, howMany );\n\t}\n\n\tconst result = this._getTransformedByDocumentChange( changeType, deltaType, targetPosition, howMany, sourcePosition );\n\n\t// Decide whether moved part should be included in the range.\n\t//\n\t// First, this concerns only `move` change, because insert change includes inserted part always (changeType == 'move').\n\t// Second, this is a case only if moved range was intersecting with this range and was inserted into this range (result.length == 3).\n\tif ( ( changeType == 'move' || changeType == 'remove' || changeType == 'reinsert' ) && result.length == 3 ) {\n\t\t// `result[ 2 ]` is a \"common part\" of this range and moved range. We substitute that common part with the whole\n\t\t// `targetRange` because we want to include whole `targetRange` in this range.\n\t\tresult[ 2 ] = targetRange;\n\t}\n\n\tconst updated = Range.createFromRanges( result );\n\n\tconst boundariesChanged = !updated.isEqual( this );\n\n\tconst rangeExpanded = this.containsPosition( targetPosition );\n\tconst rangeShrunk = sourcePosition && ( this.containsPosition( sourcePosition ) || this.start.isEqual( sourcePosition ) );\n\tconst contentChanged = rangeExpanded || rangeShrunk;\n\n\tif ( boundariesChanged ) {\n\t\t// If range boundaries have changed, fire `change:range` event.\n\t\tconst oldRange = Range.createFromRange( this );\n\n\t\tthis.start = updated.start;\n\t\tthis.end = updated.end;\n\n\t\tthis.fire( 'change:range', oldRange, {\n\t\t\ttype: changeType,\n\t\t\tbatch,\n\t\t\trange: targetRange,\n\t\t\tsourcePosition\n\t\t} );\n\t} else if ( contentChanged ) {\n\t\t// If range boundaries have not changed, but there was change inside the range, fire `change:content` event.\n\t\tthis.fire( 'change:content', Range.createFromRange( this ), {\n\t\t\ttype: changeType,\n\t\t\tbatch,\n\t\t\trange: targetRange,\n\t\t\tsourcePosition\n\t\t} );\n\t}\n}\n\nmix( LiveRange, EmitterMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/liverange.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/mapsequal\n */\n\n/**\n * Checks whether given {Map}s are equal, that is has same size and same key-value pairs.\n *\n * @returns {Boolean} `true` if given maps are equal, `false` otherwise.\n */\nexport default function mapsEqual( mapA, mapB ) {\n\tif ( mapA.size != mapB.size ) {\n\t\treturn false;\n\t}\n\n\tfor ( const attr of mapA.entries() ) {\n\t\tconst valA = JSON.stringify( attr[ 1 ] );\n\t\tconst valB = JSON.stringify( mapB.get( attr[ 0 ] ) );\n\n\t\tif ( valA !== valB ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/mapsequal.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/selection\n */\n\nimport Position from './position';\nimport Element from './element';\nimport Range from './range';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport toMap from '@ckeditor/ckeditor5-utils/src/tomap';\nimport mapsEqual from '@ckeditor/ckeditor5-utils/src/mapsequal';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * `Selection` is a group of {@link module:engine/model/range~Range ranges} which has a direction specified by\n * {@link module:engine/model/selection~Selection#anchor anchor} and {@link module:engine/model/selection~Selection#focus focus}.\n * Additionally, `Selection` may have it's own attributes.\n */\nexport default class Selection {\n\t/**\n\t * Creates new selection instance.\n\t *\n\t * @param {Iterable.<module:engine/view/range~Range>} [ranges] An optional iterable object of ranges to set.\n\t * @param {Boolean} [isLastBackward] An optional 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\tconstructor( ranges, isLastBackward ) {\n\t\t/**\n\t\t * Specifies whether the last added range was added as a backward or forward range.\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._lastRangeBackward = false;\n\n\t\t/**\n\t\t * Stores selection ranges.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/model/range~Range>}\n\t\t */\n\t\tthis._ranges = [];\n\n\t\t/**\n\t\t * List of attributes set on current selection.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map} module:engine/model/selection~Selection#_attrs\n\t\t */\n\t\tthis._attrs = new Map();\n\n\t\tif ( ranges ) {\n\t\t\tthis.setRanges( ranges, isLastBackward );\n\t\t}\n\t}\n\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~Range#start start} or\n\t * {@link module:engine/model/range~Range#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 * @readonly\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget anchor() {\n\t\tif ( this._ranges.length > 0 ) {\n\t\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\n\t\t\treturn this._lastRangeBackward ? range.end : range.start;\n\t\t}\n\n\t\treturn null;\n\t}\n\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 * @readonly\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget focus() {\n\t\tif ( this._ranges.length > 0 ) {\n\t\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\n\t\t\treturn this._lastRangeBackward ? range.start : range.end;\n\t\t}\n\n\t\treturn null;\n\t}\n\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\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\tconst length = this._ranges.length;\n\n\t\tif ( length === 1 ) {\n\t\t\treturn this._ranges[ 0 ].isCollapsed;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Returns number of ranges in selection.\n\t *\n\t * @type {Number}\n\t */\n\tget rangeCount() {\n\t\treturn this._ranges.length;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus}\n\t * precedes {@link #anchor}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isBackward() {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\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 {module:engine/model/selection~Selection} otherSelection Selection to compare with.\n\t * @returns {Boolean} `true` if selections are equal, `false` otherwise.\n\t */\n\tisEqual( otherSelection ) {\n\t\tif ( this.rangeCount != otherSelection.rangeCount ) {\n\t\t\treturn false;\n\t\t} else if ( this.rangeCount === 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !this.anchor.isEqual( otherSelection.anchor ) || !this.focus.isEqual( otherSelection.focus ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const thisRange of this._ranges ) {\n\t\t\tlet found = false;\n\n\t\t\tfor ( const otherRange of otherSelection._ranges ) {\n\t\t\t\tif ( thisRange.isEqual( otherRange ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over copies of selection ranges.\n\t *\n\t * @returns {Iterator.<module:engine/model/range~Range>}\n\t */\n\t* getRanges() {\n\t\tfor ( const range of this._ranges ) {\n\t\t\tyield Range.createFromRange( range );\n\t\t}\n\t}\n\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~Range#start start} position\n\t * {@link module:engine/model/position~Position#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\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetFirstRange() {\n\t\tlet first = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !first || range.start.isBefore( first.start ) ) {\n\t\t\t\tfirst = range;\n\t\t\t}\n\t\t}\n\n\t\treturn first ? Range.createFromRange( first ) : null;\n\t}\n\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~Range#end end} position\n\t * {@link module:engine/model/position~Position#isAfter is after} end position of all other ranges (not to confuse with the range most\n\t * recently added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetLastRange() {\n\t\tlet last = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !last || range.end.isAfter( last.end ) ) {\n\t\t\t\tlast = range;\n\t\t\t}\n\t\t}\n\n\t\treturn last ? Range.createFromRange( last ) : null;\n\t}\n\n\t/**\n\t * Returns the first position in the selection.\n\t * First position is the position that {@link module:engine/model/position~Position#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\t * @returns {module:engine/model/position~Position|null}\n\t */\n\tgetFirstPosition() {\n\t\tconst first = this.getFirstRange();\n\n\t\treturn first ? Position.createFromPosition( first.start ) : null;\n\t}\n\n\t/**\n\t * Returns the last position in the selection.\n\t * Last position is the position that {@link module:engine/model/position~Position#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\t * @returns {module:engine/model/position~Position|null}\n\t */\n\tgetLastPosition() {\n\t\tconst lastRange = this.getLastRange();\n\n\t\treturn lastRange ? Position.createFromPosition( lastRange.end ) : null;\n\t}\n\n\t/**\n\t * Adds a range to this selection. Added range is copied. This means that passed range is not saved in `Selection`\n\t * instance and operating on it will not change `Selection` state.\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/model/range~Range#start start} to {@link module:engine/model/range~Range#end end}\n\t * or from {@link module:engine/model/range~Range#end end}\n\t * to {@link module:engine/model/range~Range#start start}.\n\t * The flag is used to set {@link #anchor} and\n\t * {@link #focus} properties.\n\t *\n\t * @fires change:range\n\t * @param {module:engine/model/range~Range} range Range to add.\n\t * @param {Boolean} [isBackward=false] Flag describing if added range was selected forward - from start to end (`false`)\n\t * or backward - from end to start (`true`).\n\t */\n\taddRange( range, isBackward = false ) {\n\t\tthis._pushRange( range );\n\t\tthis._lastRangeBackward = !!isBackward;\n\n\t\tthis.fire( 'change:range', { directChange: true } );\n\t}\n\n\t/**\n\t * Removes all ranges that were added to the selection.\n\t *\n\t * @fires change:range\n\t */\n\tremoveAllRanges() {\n\t\tif ( this._ranges.length > 0 ) {\n\t\t\tthis._removeAllRanges();\n\t\t\tthis.fire( 'change:range', { directChange: true } );\n\t\t}\n\t}\n\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~Selection#anchor} and\n\t * {@link module:engine/model/selection~Selection#focus}. Accepts a flag describing in which direction the selection is made\n\t * (see {@link module:engine/model/selection~Selection#addRange}).\n\t *\n\t * @fires change:range\n\t * @param {Iterable.<module:engine/model/range~Range>} newRanges Ranges to set.\n\t * @param {Boolean} [isLastBackward=false] 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\tsetRanges( newRanges, isLastBackward = false ) {\n\t\tnewRanges = Array.from( newRanges );\n\n\t\t// Check whether there is any range in new ranges set that is different than all already added ranges.\n\t\tconst anyNewRange = newRanges.some( newRange => {\n\t\t\tif ( !( newRange instanceof Range ) ) {\n\t\t\t\tthrow new CKEditorError( 'model-selection-added-not-range: Trying to add an object that is not an instance of Range.' );\n\t\t\t}\n\n\t\t\treturn this._ranges.every( oldRange => {\n\t\t\t\treturn !oldRange.isEqual( newRange );\n\t\t\t} );\n\t\t} );\n\n\t\t// Don't do anything if nothing changed.\n\t\tif ( newRanges.length === this._ranges.length && !anyNewRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._removeAllRanges();\n\n\t\tfor ( const range of newRanges ) {\n\t\t\tthis._pushRange( range );\n\t\t}\n\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\n\t\tthis.fire( 'change:range', { directChange: true } );\n\t}\n\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~Selection selection}, {@link module:engine/model/position~Position position},\n\t * {@link module:engine/model/range~Range range} or an iterable of {@link module:engine/model/range~Range ranges}.\n\t *\n\t * @param {module:engine/model/selection~Selection|module:engine/model/position~Position|\n\t * Iterable.<module:engine/model/range~Range>|module:engine/model/range~Range} selectable\n\t */\n\tsetTo( selectable ) {\n\t\tif ( selectable instanceof Selection ) {\n\t\t\tthis.setRanges( selectable.getRanges(), selectable.isBackward );\n\t\t} else if ( selectable instanceof Range ) {\n\t\t\tthis.setRanges( [ selectable ] );\n\t\t} else if ( isIterable( selectable ) ) {\n\t\t\t// We assume that the selectable is an iterable of ranges.\n\t\t\tthis.setRanges( selectable );\n\t\t} else {\n\t\t\t// We assume that the selectable is a position.\n\t\t\tthis.setRanges( [ new Range( selectable ) ] );\n\t\t}\n\t}\n\n\t/**\n\t * Sets this selection in the provided element.\n\t *\n\t * @param {module:engine/model/element~Element} element\n\t */\n\tsetIn( element ) {\n\t\tthis.setRanges( [ Range.createIn( element ) ] );\n\t}\n\n\t/**\n\t * Sets this selection on the provided item.\n\t *\n\t * @param {module:engine/model/item~Item} item\n\t */\n\tsetOn( item ) {\n\t\tthis.setRanges( [ Range.createOn( item ) ] );\n\t}\n\n\t/**\n\t * Sets collapsed selection at the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/model/position~Position.createAt} parameters.\n\t *\n\t * @fires change:range\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tsetCollapsedAt( itemOrPosition, offset ) {\n\t\tconst pos = Position.createAt( itemOrPosition, offset );\n\t\tconst range = new Range( pos, pos );\n\n\t\tthis.setRanges( [ range ] );\n\t}\n\n\t/**\n\t * Collapses selection to the selection's {@link module:engine/model/selection~Selection#getFirstPosition first position}.\n\t * All ranges, besides the collapsed one, will be removed. Nothing will change if there are no ranges stored\n\t * inside selection.\n\t *\n\t * @fires change\n\t */\n\tcollapseToStart() {\n\t\tconst startPosition = this.getFirstPosition();\n\n\t\tif ( startPosition !== null ) {\n\t\t\tthis.setRanges( [ new Range( startPosition, startPosition ) ] );\n\t\t}\n\t}\n\n\t/**\n\t * Collapses selection to the selection's {@link module:engine/model/selection~Selection#getLastPosition last position}.\n\t * All ranges, besides the collapsed one, will be removed. Nothing will change if there are no ranges stored\n\t * inside selection.\n\t *\n\t * @fires change\n\t */\n\tcollapseToEnd() {\n\t\tconst endPosition = this.getLastPosition();\n\n\t\tif ( endPosition !== null ) {\n\t\t\tthis.setRanges( [ new Range( endPosition, endPosition ) ] );\n\t\t}\n\t}\n\n\t/**\n\t * Moves {@link module:engine/model/selection~Selection#focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/model/position~Position.createAt} parameters.\n\t *\n\t * @fires change:range\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tmoveFocusTo( itemOrPosition, offset ) {\n\t\tif ( this.anchor === null ) {\n\t\t\t/**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error model-selection-moveFocusTo-no-ranges\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-selection-moveFocusTo-no-ranges: Cannot set selection focus if there are no ranges in selection.'\n\t\t\t);\n\t\t}\n\n\t\tconst newFocus = Position.createAt( itemOrPosition, offset );\n\n\t\tif ( newFocus.compareWith( this.focus ) == 'same' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst anchor = this.anchor;\n\n\t\tif ( this._ranges.length ) {\n\t\t\tthis._popRange();\n\t\t}\n\n\t\tif ( newFocus.compareWith( anchor ) == 'before' ) {\n\t\t\tthis.addRange( new Range( newFocus, anchor ), true );\n\t\t} else {\n\t\t\tthis.addRange( new Range( anchor, newFocus ) );\n\t\t}\n\t}\n\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 {String} 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\n\t/**\n\t * Returns iterator 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\t * @returns {Iterable.<*>}\n\t */\n\tgetAttributes() {\n\t\treturn this._attrs.entries();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this selection's attribute keys.\n\t *\n\t * @returns {Iterator.<String>}\n\t */\n\tgetAttributeKeys() {\n\t\treturn this._attrs.keys();\n\t}\n\n\t/**\n\t * Checks if the selection has an attribute for given key.\n\t *\n\t * @param {String} key Key of attribute to check.\n\t * @returns {Boolean} `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\n\t/**\n\t * Removes all attributes from the selection.\n\t *\n\t * If there were any attributes in selection, fires the {@link #event:change} event with\n\t * removed attributes' keys.\n\t *\n\t * @fires change:attribute\n\t */\n\tclearAttributes() {\n\t\tif ( this._attrs.size > 0 ) {\n\t\t\tconst attributeKeys = Array.from( this._attrs.keys() );\n\t\t\tthis._attrs.clear();\n\n\t\t\tthis.fire( 'change:attribute', { attributeKeys, directChange: true } );\n\t\t}\n\t}\n\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} event with\n\t * removed attribute key.\n\t *\n\t * @fires change:attribute\n\t * @param {String} 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\n\t\t\tthis.fire( 'change:attribute', { attributeKeys: [ key ], directChange: true } );\n\t\t}\n\t}\n\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} event with\n\t * the attribute key.\n\t *\n\t * @fires change:attribute\n\t * @param {String} 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\n\t\t\tthis.fire( 'change:attribute', { attributeKeys: [ key ], directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Removes all attributes from the selection and sets given attributes.\n\t *\n\t * If given set of attributes is different than set of attributes already added to selection, fires\n\t * {@link #event:change change event} with keys of attributes that changed.\n\t *\n\t * @fires event:change:attribute\n\t * @param {Iterable|Object} attrs Iterable object containing attributes to be set.\n\t */\n\tsetAttributesTo( attrs ) {\n\t\tattrs = toMap( attrs );\n\n\t\tif ( !mapsEqual( attrs, this._attrs ) ) {\n\t\t\t// Create a set from keys of old and new attributes.\n\t\t\tconst changed = new Set( Array.from( attrs.keys() ).concat( Array.from( this._attrs.keys() ) ) );\n\n\t\t\tfor ( const [ key, value ] of attrs ) {\n\t\t\t\t// If the attribute remains unchanged, remove it from changed set.\n\t\t\t\tif ( this._attrs.get( key ) === value ) {\n\t\t\t\t\tchanged.delete( key );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._attrs = attrs;\n\n\t\t\tthis.fire( 'change:attribute', { attributeKeys: Array.from( changed ), directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/model/element~Element 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\t * @returns {module:engine/model/element~Element|null}\n\t */\n\tgetSelectedElement() {\n\t\tif ( this.rangeCount !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst range = this.getFirstRange();\n\t\tconst nodeAfterStart = range.start.nodeAfter;\n\t\tconst nodeBeforeEnd = range.end.nodeBefore;\n\n\t\treturn ( nodeAfterStart instanceof Element && nodeAfterStart == nodeBeforeEnd ) ? nodeAfterStart : null;\n\t}\n\n\t/**\n\t * Gets elements of type \"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()` always returns the deepest block.\n\t *\n\t * In this case the function will return exactly all 3 paragraphs:\n\t *\n\t *\t\t<paragraph>[a</paragraph>\n\t *\t\t<quote>\n\t *\t\t\t<paragraph>b</paragraph>\n\t *\t\t</quote>\n\t *\t\t<paragraph>c]d</paragraph>\n\t *\n\t * In this case the paragraph will also be returned, despite the collapsed selection:\n\t *\n\t *\t\t<paragraph>[]a</paragraph>\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 *\t\t<paragraph>[a</paragraph>\n\t *\t\t<paragraph>b</paragraph>\n\t *\t\t<paragraph>]c</paragraph> // this block will not be returned\n\t *\n\t * @returns {Iterator.<module:engine/model/element~Element>}\n\t */\n\t* getSelectedBlocks() {\n\t\tconst visited = new WeakSet();\n\n\t\tfor ( const range of this.getRanges() ) {\n\t\t\tconst startBlock = getParentBlock( range.start, visited );\n\n\t\t\tif ( startBlock ) {\n\t\t\t\tyield startBlock;\n\t\t\t}\n\n\t\t\tfor ( const value of range.getWalker() ) {\n\t\t\t\tif ( value.type == 'elementEnd' && isUnvisitedBlockContainer( value.item, visited ) ) {\n\t\t\t\t\tyield value.item;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst endBlock = getParentBlock( range.end, visited );\n\n\t\t\t// #984. Don't return the end block if the range ends right at its beginning.\n\t\t\tif ( endBlock && !range.end.isTouching( Position.createAt( endBlock ) ) ) {\n\t\t\t\tyield endBlock;\n\t\t\t}\n\t\t}\n\t}\n\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~Position#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\t * @param {module:engine/model/element~Element} [element=this.anchor.root]\n\t * @returns {Boolean}\n\t */\n\tcontainsEntireContent( element = this.anchor.root ) {\n\t\tconst limitStartPosition = Position.createAt( element );\n\t\tconst limitEndPosition = Position.createAt( element, 'end' );\n\n\t\treturn limitStartPosition.isTouching( this.getFirstPosition() ) &&\n\t\t\tlimitEndPosition.isTouching( this.getLastPosition() );\n\t}\n\n\t/**\n\t * Creates and returns an instance of `Selection` that is a clone of given selection, meaning that it has same\n\t * ranges and same direction as this selection.\n\t *\n\t * @params {module:engine/model/selection~Selection} otherSelection Selection to be cloned.\n\t * @returns {module:engine/model/selection~Selection} `Selection` instance that is a clone of given selection.\n\t */\n\tstatic createFromSelection( otherSelection ) {\n\t\tconst selection = new this();\n\t\tselection.setTo( otherSelection );\n\n\t\treturn selection;\n\t}\n\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 * @protected\n\t * @param {module:engine/model/range~Range} range Range to add.\n\t */\n\t_pushRange( range ) {\n\t\tif ( !( range instanceof Range ) ) {\n\t\t\tthrow new CKEditorError( 'model-selection-added-not-range: Trying to add an object that is not an instance of Range.' );\n\t\t}\n\n\t\tthis._checkRange( range );\n\t\tthis._ranges.push( Range.createFromRange( range ) );\n\t}\n\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 * @protected\n\t * @param {module:engine/model/range~Range} range Range to check.\n\t */\n\t_checkRange( range ) {\n\t\tfor ( let i = 0; i < this._ranges.length; i++ ) {\n\t\t\tif ( range.isIntersecting( this._ranges[ i ] ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to add a range that intersects with another range from selection.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-range-intersects\n\t\t\t\t * @param {module:engine/model/range~Range} addedRange Range that was added to the selection.\n\t\t\t\t * @param {module:engine/model/range~Range} intersectingRange Range from selection that intersects with `addedRange`.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-selection-range-intersects: Trying to add a range that intersects with another range from selection.',\n\t\t\t\t\t{ addedRange: range, intersectingRange: this._ranges[ i ] }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes most recently added range from the selection.\n\t *\n\t * @protected\n\t */\n\t_popRange() {\n\t\tthis._ranges.pop();\n\t}\n\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 * @private\n\t */\n\t_removeAllRanges() {\n\t\twhile ( this._ranges.length > 0 ) {\n\t\t\tthis._popRange();\n\t\t}\n\t}\n\n\t/**\n\t * @event change\n\t */\n\n\t/**\n\t * Fired whenever selection ranges are changed.\n\t *\n\t * @event change:range\n\t * @param {Boolean} directChange Specifies whether the range change was caused by direct usage of `Selection` API (`true`)\n\t * or by changes done to {@link module:engine/model/document~Document model document}\n\t * using {@link module:engine/model/batch~Batch Batch} API (`false`).\n\t */\n\n\t/**\n\t * Fired whenever selection attributes are changed.\n\t *\n\t * @event change:attribute\n\t * @param {Boolean} directChange Specifies whether the attributes changed by direct usage of the Selection API (`true`)\n\t * or by changes done to the {@link module:engine/model/document~Document model document}\n\t * using the {@link module:engine/model/batch~Batch Batch} API (`false`).\n\t * @param {Array.<String>} attributeKeys Array containing keys of attributes that changed.\n\t */\n}\n\nmix( Selection, EmitterMixin );\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.\nfunction isUnvisitedBlockContainer( element, visited ) {\n\tif ( visited.has( element ) ) {\n\t\treturn false;\n\t}\n\n\tvisited.add( element );\n\n\t// TODO https://github.com/ckeditor/ckeditor5-engine/issues/532#issuecomment-278900072.\n\t// This should not be a `$block` check.\n\treturn element.document.schema.itemExtends( element.name, '$block' ) && element.parent;\n}\n\n// Finds the lowest element in position's ancestors which is a block.\n// Marks all ancestors as already visited to not include any of them later on.\nfunction getParentBlock( position, visited ) {\n\tconst ancestors = position.parent.getAncestors( { parentFirst: true, includeSelf: true } );\n\tconst block = ancestors.find( element => isUnvisitedBlockContainer( element, visited ) );\n\n\t// Mark all ancestors of this position's parent, because find() might've stopped early and\n\t// the found block may be a child of another block.\n\tancestors.forEach( element => visited.add( element ) );\n\n\treturn block;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/selection.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/documentselection\n */\n\nimport Position from './position';\nimport Range from './range';\nimport LiveRange from './liverange';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport toMap from '@ckeditor/ckeditor5-utils/src/tomap';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\nimport Selection from './selection';\n\nconst storePrefix = 'selection:';\n\nconst attrOpTypes = new Set(\n\t[ 'addAttribute', 'removeAttribute', 'changeAttribute', 'addRootAttribute', 'removeRootAttribute', 'changeRootAttribute' ]\n);\n\n/**\n * `DocumentSelection` is a special selection which is used as the\n * {@link module:engine/model/document~Document#selection document's selection}.\n * There can be only one instance of `DocumentSelection` per document.\n *\n * `DocumentSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document 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~Selection} and `DocumentSelection` are:\n * * there is always a range in `DocumentSelection` - 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 `DocumentSelection` are updated automatically according to selection ranges.\n *\n * Since `DocumentSelection` uses {@link module:engine/model/liverange~LiveRange live ranges}\n * and is updated when {@link module:engine/model/document~Document document}\n * changes, it cannot be set on {@link module:engine/model/node~Node nodes}\n * that are inside {@link module:engine/model/documentfragment~DocumentFragment document fragment}.\n * If you need to represent a selection in document fragment,\n * use {@link module:engine/model/selection~Selection Selection class} instead.\n *\n * @extends module:engine/model/selection~Selection\n */\nexport default class DocumentSelection extends Selection {\n\t/**\n\t * Creates an empty live selection for given {@link module:engine/model/document~Document}.\n\t *\n\t * @param {module:engine/model/document~Document} document Document which owns this selection.\n\t */\n\tconstructor( document ) {\n\t\tsuper();\n\n\t\t/**\n\t\t * Document which owns this selection.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:engine/model/document~Document} module:engine/model/documentselection~DocumentSelection#_document\n\t\t */\n\t\tthis._document = document;\n\n\t\t/**\n\t\t * Keeps mapping of attribute name to priority with which the attribute got modified (added/changed/removed)\n\t\t * last time. Possible values of priority are: `'low'` and `'normal'`.\n\t\t *\n\t\t * Priorities are used by internal `DocumentSelection` mechanisms. All attributes set using `DocumentSelection`\n\t\t * attributes API are set with `'normal'` priority.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/model/documentselection~DocumentSelection#_attributePriority\n\t\t */\n\t\tthis._attributePriority = new Map();\n\n\t\tthis.listenTo( this._document, 'change', ( evt, type, changes, batch ) => {\n\t\t\t// Whenever attribute operation is performed on document, update selection attributes.\n\t\t\t// This is not the most efficient way to update selection attributes, but should be okay for now.\n\t\t\tif ( attrOpTypes.has( type ) ) {\n\t\t\t\tthis._updateAttributes( false );\n\t\t\t}\n\n\t\t\t// Whenever element which had selection's attributes stored in it stops being empty,\n\t\t\t// the attributes need to be removed.\n\t\t\tclearAttributesStoredInElement( changes, batch, this._document );\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget isCollapsed() {\n\t\tconst length = this._ranges.length;\n\n\t\treturn length === 0 ? this._document._getDefaultRange().isCollapsed : super.isCollapsed;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget anchor() {\n\t\treturn super.anchor || this._document._getDefaultRange().start;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget focus() {\n\t\treturn super.focus || this._document._getDefaultRange().end;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget rangeCount() {\n\t\treturn this._ranges.length ? this._ranges.length : 1;\n\t}\n\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~Document#_getDefaultRange document's default range}.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget hasOwnRange() {\n\t\treturn this._ranges.length > 0;\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by document selection.\n\t */\n\tdestroy() {\n\t\tfor ( let i = 0; i < this._ranges.length; i++ ) {\n\t\t\tthis._ranges[ i ].detach();\n\t\t}\n\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t* getRanges() {\n\t\tif ( this._ranges.length ) {\n\t\t\tyield* super.getRanges();\n\t\t} else {\n\t\t\tyield this._document._getDefaultRange();\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tgetFirstRange() {\n\t\treturn super.getFirstRange() || this._document._getDefaultRange();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tgetLastRange() {\n\t\treturn super.getLastRange() || this._document._getDefaultRange();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\taddRange( range, isBackward = false ) {\n\t\tsuper.addRange( range, isBackward );\n\t\tthis.refreshAttributes();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tremoveAllRanges() {\n\t\tsuper.removeAllRanges();\n\t\tthis.refreshAttributes();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tsetRanges( newRanges, isLastBackward = false ) {\n\t\tsuper.setRanges( newRanges, isLastBackward );\n\t\tthis.refreshAttributes();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tsetAttribute( key, value ) {\n\t\t// Store attribute in parent element if the selection is collapsed in an empty node.\n\t\tif ( this.isCollapsed && this.anchor.parent.isEmpty ) {\n\t\t\tthis._storeAttribute( key, value );\n\t\t}\n\n\t\tif ( this._setAttribute( key, value ) ) {\n\t\t\t// Fire event with exact data.\n\t\t\tconst attributeKeys = [ key ];\n\t\t\tthis.fire( 'change:attribute', { attributeKeys, directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tremoveAttribute( key ) {\n\t\t// Remove stored attribute from parent element if the selection is collapsed in an empty node.\n\t\tif ( this.isCollapsed && this.anchor.parent.isEmpty ) {\n\t\t\tthis._removeStoredAttribute( key );\n\t\t}\n\n\t\tif ( this._removeAttribute( key ) ) {\n\t\t\t// Fire event with exact data.\n\t\t\tconst attributeKeys = [ key ];\n\t\t\tthis.fire( 'change:attribute', { attributeKeys, directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tsetAttributesTo( attrs ) {\n\t\tattrs = toMap( attrs );\n\n\t\tif ( this.isCollapsed && this.anchor.parent.isEmpty ) {\n\t\t\tthis._setStoredAttributesTo( attrs );\n\t\t}\n\n\t\tconst changed = this._setAttributesTo( attrs );\n\n\t\tif ( changed.size > 0 ) {\n\t\t\t// Fire event with exact data (fire only if anything changed).\n\t\t\tconst attributeKeys = Array.from( changed );\n\t\t\tthis.fire( 'change:attribute', { attributeKeys, directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tclearAttributes() {\n\t\tthis.setAttributesTo( [] );\n\t}\n\n\t/**\n\t * Removes all attributes from the selection and sets attributes according to the surrounding nodes.\n\t */\n\trefreshAttributes() {\n\t\tthis._updateAttributes( true );\n\t}\n\n\t/**\n\t * This method is not available in `DocumentSelection`. There can be only one\n\t * `DocumentSelection` per document instance, so creating new `DocumentSelection`s this way\n\t * would be unsafe.\n\t */\n\tstatic createFromSelection() {\n\t\t/**\n\t\t * Cannot create a new `DocumentSelection` instance.\n\t\t *\n\t\t * `DocumentSelection#createFromSelection()` is not available. There can be only one\n\t\t * `DocumentSelection` per document instance, so creating new `DocumentSelection`s this way\n\t\t * would be unsafe.\n\t\t *\n\t\t * @error documentselection-cannot-create\n\t\t */\n\t\tthrow new CKEditorError( 'documentselection-cannot-create: Cannot create a new DocumentSelection instance.' );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_popRange() {\n\t\tthis._ranges.pop().detach();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_pushRange( range ) {\n\t\tconst liveRange = this._prepareRange( range );\n\n\t\t// `undefined` is returned when given `range` is in graveyard root.\n\t\tif ( liveRange ) {\n\t\t\tthis._ranges.push( liveRange );\n\t\t}\n\t}\n\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~LiveRange LiveRange}\n\t * and sets listeners listening to the range's change event.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range\n\t */\n\t_prepareRange( range ) {\n\t\tif ( !( range instanceof Range ) ) {\n\t\t\t/**\n\t\t\t * Trying to add an object that is not an instance of Range.\n\t\t\t *\n\t\t\t * @error model-selection-added-not-range\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-selection-added-not-range: Trying to add an object that is not an instance of Range.' );\n\t\t}\n\n\t\tif ( range.root == this._document.graveyard ) {\n\t\t\t/**\n\t\t\t * Trying to add a Range that is in the graveyard root. Range rejected.\n\t\t\t *\n\t\t\t * @warning model-selection-range-in-graveyard\n\t\t\t */\n\t\t\tlog.warn( 'model-selection-range-in-graveyard: Trying to add a Range that is in the graveyard root. Range rejected.' );\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis._checkRange( range );\n\n\t\tconst liveRange = LiveRange.createFromRange( range );\n\n\t\tthis.listenTo( liveRange, 'change:range', ( evt, oldRange, data ) => {\n\t\t\t// If `LiveRange` is in whole moved to the graveyard, fix that range.\n\t\t\tif ( liveRange.root == this._document.graveyard ) {\n\t\t\t\tthis._fixGraveyardSelection( liveRange, data.sourcePosition );\n\t\t\t}\n\n\t\t\t// Whenever a live range from selection changes, fire an event informing about that change.\n\t\t\tthis.fire( 'change:range', { directChange: false } );\n\t\t} );\n\n\t\treturn liveRange;\n\t}\n\n\t/**\n\t * Updates this selection attributes according to its ranges and the {@link module:engine/model/document~Document model document}.\n\t *\n\t * @protected\n\t * @param {Boolean} clearAll\n\t * @fires change:attribute\n\t */\n\t_updateAttributes( clearAll ) {\n\t\tconst newAttributes = toMap( this._getSurroundingAttributes() );\n\t\tconst oldAttributes = toMap( this.getAttributes() );\n\n\t\tif ( clearAll ) {\n\t\t\t// If `clearAll` remove all attributes and reset priorities.\n\t\t\tthis._attributePriority = new Map();\n\t\t\tthis._attrs = new Map();\n\t\t} else {\n\t\t\t// If not, remove only attributes added with `low` priority.\n\t\t\tfor ( const [ key, priority ] of this._attributePriority ) {\n\t\t\t\tif ( priority == 'low' ) {\n\t\t\t\t\tthis._attrs.delete( key );\n\t\t\t\t\tthis._attributePriority.delete( key );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._setAttributesTo( newAttributes, false );\n\n\t\t// Let's evaluate which attributes really changed.\n\t\tconst changed = [];\n\n\t\t// First, loop through all attributes that are set on selection right now.\n\t\t// Check which of them are different than old attributes.\n\t\tfor ( const [ newKey, newValue ] of this.getAttributes() ) {\n\t\t\tif ( !oldAttributes.has( newKey ) || oldAttributes.get( newKey ) !== newValue ) {\n\t\t\t\tchanged.push( newKey );\n\t\t\t}\n\t\t}\n\n\t\t// Then, check which of old attributes got removed.\n\t\tfor ( const [ oldKey ] of oldAttributes ) {\n\t\t\tif ( !this.hasAttribute( oldKey ) ) {\n\t\t\t\tchanged.push( oldKey );\n\t\t\t}\n\t\t}\n\n\t\t// Fire event with exact data (fire only if anything changed).\n\t\tif ( changed.length > 0 ) {\n\t\t\tthis.fire( 'change:attribute', { attributeKeys: changed, directChange: false } );\n\t\t}\n\t}\n\n\t/**\n\t * Generates and returns an attribute key for selection attributes store, basing on original attribute key.\n\t *\n\t * @protected\n\t * @param {String} key Attribute key to convert.\n\t * @returns {String} Converted attribute key, applicable for selection store.\n\t */\n\tstatic _getStoreAttributeKey( key ) {\n\t\treturn storePrefix + key;\n\t}\n\n\t/**\n\t * Checks whether the given attribute key is an attribute stored on an element.\n\t *\n\t * @protected\n\t * @param {String} key\n\t * @returns {Boolean}\n\t */\n\tstatic _isStoreAttributeKey( key ) {\n\t\treturn key.startsWith( storePrefix );\n\t}\n\n\t/**\n\t * Internal method for setting `DocumentSelection` attribute. Supports attribute priorities (through `directChange`\n\t * parameter).\n\t *\n\t * @private\n\t * @param {String} key Attribute key.\n\t * @param {*} value Attribute value.\n\t * @param {Boolean} [directChange=true] `true` if the change is caused by `Selection` API, `false` if change\n\t * is caused by `Batch` API.\n\t * @returns {Boolean} Whether value has changed.\n\t */\n\t_setAttribute( key, value, directChange = true ) {\n\t\tconst priority = directChange ? 'normal' : 'low';\n\n\t\tif ( priority == 'low' && this._attributePriority.get( key ) == 'normal' ) {\n\t\t\t// Priority too low.\n\t\t\treturn false;\n\t\t}\n\n\t\tconst oldValue = super.getAttribute( key );\n\n\t\t// Don't do anything if value has not changed.\n\t\tif ( oldValue === value ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis._attrs.set( key, value );\n\n\t\t// Update priorities map.\n\t\tthis._attributePriority.set( key, priority );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Internal method for removing `DocumentSelection` attribute. Supports attribute priorities (through `directChange`\n\t * parameter).\n\t *\n\t * @private\n\t * @param {String} key Attribute key.\n\t * @param {Boolean} [directChange=true] `true` if the change is caused by `Selection` API, `false` if change\n\t * is caused by `Batch` API.\n\t * @returns {Boolean} Whether attribute was removed. May not be true if such attributes didn't exist or the\n\t * existing attribute had higher priority.\n\t */\n\t_removeAttribute( key, directChange = true ) {\n\t\tconst priority = directChange ? 'normal' : 'low';\n\n\t\tif ( priority == 'low' && this._attributePriority.get( key ) == 'normal' ) {\n\t\t\t// Priority too low.\n\t\t\treturn false;\n\t\t}\n\n\t\t// Don't do anything if value has not changed.\n\t\tif ( !super.hasAttribute( key ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis._attrs.delete( key );\n\n\t\t// Update priorities map.\n\t\tthis._attributePriority.set( key, priority );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Internal method for setting multiple `DocumentSelection` attributes. Supports attribute priorities (through\n\t * `directChange` parameter).\n\t *\n\t * @private\n\t * @param {Iterable|Object} attrs Iterable object containing attributes to be set.\n\t * @param {Boolean} [directChange=true] `true` if the change is caused by `Selection` API, `false` if change\n\t * is caused by `Batch` API.\n\t * @returns {Set.<String>} Changed attribute keys.\n\t */\n\t_setAttributesTo( attrs, directChange = true ) {\n\t\tconst changed = new Set();\n\n\t\tfor ( const [ oldKey, oldValue ] of this.getAttributes() ) {\n\t\t\t// Do not remove attribute if attribute with same key and value is about to be set.\n\t\t\tif ( attrs.get( oldKey ) === oldValue ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Attribute still might not get removed because of priorities.\n\t\t\tif ( this._removeAttribute( oldKey, directChange ) ) {\n\t\t\t\tchanged.add( oldKey );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const [ key, value ] of attrs ) {\n\t\t\t// Attribute may not be set because of attributes or because same key/value is already added.\n\t\t\tconst gotAdded = this._setAttribute( key, value, directChange );\n\n\t\t\tif ( gotAdded ) {\n\t\t\t\tchanged.add( key );\n\t\t\t}\n\t\t}\n\n\t\treturn changed;\n\t}\n\n\t/**\n\t * Returns an iterator that iterates through all selection attributes stored in current selection's parent.\n\t *\n\t * @private\n\t * @returns {Iterable.<*>}\n\t */\n\t* _getStoredAttributes() {\n\t\tconst selectionParent = this.getFirstPosition().parent;\n\n\t\tif ( this.isCollapsed && selectionParent.isEmpty ) {\n\t\t\tfor ( const key of selectionParent.getAttributeKeys() ) {\n\t\t\t\tif ( key.startsWith( storePrefix ) ) {\n\t\t\t\t\tconst realKey = key.substr( storePrefix.length );\n\n\t\t\t\t\tyield [ realKey, selectionParent.getAttribute( key ) ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes attribute with given key from attributes stored in current selection's parent node.\n\t *\n\t * @private\n\t * @param {String} key Key of attribute to remove.\n\t */\n\t_removeStoredAttribute( key ) {\n\t\tconst storeKey = DocumentSelection._getStoreAttributeKey( key );\n\n\t\tthis._document.batch().removeAttribute( this.anchor.parent, storeKey );\n\t}\n\n\t/**\n\t * Stores given attribute key and value in current selection's parent node.\n\t *\n\t * @private\n\t * @param {String} key Key of attribute to set.\n\t * @param {*} value Attribute value.\n\t */\n\t_storeAttribute( key, value ) {\n\t\tconst storeKey = DocumentSelection._getStoreAttributeKey( key );\n\n\t\tthis._document.batch().setAttribute( this.anchor.parent, storeKey, value );\n\t}\n\n\t/**\n\t * Sets selection attributes stored in current selection's parent node to given set of attributes.\n\t *\n\t * @private\n\t * @param {Iterable|Object} attrs Iterable object containing attributes to be set.\n\t */\n\t_setStoredAttributesTo( attrs ) {\n\t\tconst selectionParent = this.anchor.parent;\n\t\tconst batch = this._document.batch();\n\n\t\tfor ( const [ oldKey ] of this._getStoredAttributes() ) {\n\t\t\tconst storeKey = DocumentSelection._getStoreAttributeKey( oldKey );\n\n\t\t\tbatch.removeAttribute( selectionParent, storeKey );\n\t\t}\n\n\t\tfor ( const [ key, value ] of attrs ) {\n\t\t\tconst storeKey = DocumentSelection._getStoreAttributeKey( key );\n\n\t\t\tbatch.setAttribute( selectionParent, storeKey, value );\n\t\t}\n\t}\n\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 * @private\n\t * @returns {Iterable.<*>} Collection of attributes.\n\t */\n\t_getSurroundingAttributes() {\n\t\tconst position = this.getFirstPosition();\n\t\tconst schema = this._document.schema;\n\n\t\tlet attrs = null;\n\n\t\tif ( !this.isCollapsed ) {\n\t\t\t// 1. If selection is a range...\n\t\t\tconst range = this.getFirstRange();\n\n\t\t\t// ...look for a first character node in that range and take attributes from it.\n\t\t\tfor ( const value of range ) {\n\t\t\t\t// If the item is an object, we don't want to get attributes from its children.\n\t\t\t\tif ( value.item.is( 'element' ) && schema.objects.has( value.item.name ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// This is not an optimal solution because of https://github.com/ckeditor/ckeditor5-engine/issues/454.\n\t\t\t\t// It can be done better by using `break;` instead of checking `attrs === null`.\n\t\t\t\tif ( value.type == 'text' && attrs === null ) {\n\t\t\t\t\tattrs = value.item.getAttributes();\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// 2. If the selection is a caret or the range does not contain a character node...\n\n\t\t\tconst nodeBefore = position.textNode ? position.textNode : position.nodeBefore;\n\t\t\tconst nodeAfter = position.textNode ? position.textNode : position.nodeAfter;\n\n\t\t\t// ...look at the node before caret and take attributes from it if it is a character node.\n\t\t\tattrs = getAttrsIfCharacter( nodeBefore );\n\n\t\t\t// 3. If not, look at the node after caret...\n\t\t\tif ( !attrs ) {\n\t\t\t\tattrs = getAttrsIfCharacter( nodeAfter );\n\t\t\t}\n\n\t\t\t// 4. If not, try to find the first character on the left, that is in the same node.\n\t\t\tif ( !attrs ) {\n\t\t\t\tlet node = nodeBefore;\n\n\t\t\t\twhile ( node && !attrs ) {\n\t\t\t\t\tnode = node.previousSibling;\n\t\t\t\t\tattrs = getAttrsIfCharacter( node );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 5. If not found, try to find the first character on the right, that is in the same node.\n\t\t\tif ( !attrs ) {\n\t\t\t\tlet node = nodeAfter;\n\n\t\t\t\twhile ( node && !attrs ) {\n\t\t\t\t\tnode = node.nextSibling;\n\t\t\t\t\tattrs = getAttrsIfCharacter( node );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 6. If not found, selection should retrieve attributes from parent.\n\t\t\tif ( !attrs ) {\n\t\t\t\tattrs = this._getStoredAttributes();\n\t\t\t}\n\t\t}\n\n\t\treturn attrs;\n\t}\n\n\t/**\n\t * Fixes a selection range after it ends up in graveyard root.\n\t *\n\t * @private\n\t * @param {module:engine/model/liverange~LiveRange} liveRange The range from selection, that ended up in the graveyard root.\n\t * @param {module:engine/model/position~Position} removedRangeStart Start position of a range which was removed.\n\t */\n\t_fixGraveyardSelection( liveRange, removedRangeStart ) {\n\t\t// The start of the removed range is the closest position to the `liveRange` - the original selection range.\n\t\t// This is a good candidate for a fixed selection range.\n\t\tconst positionCandidate = Position.createFromPosition( removedRangeStart );\n\n\t\t// Find a range that is a correct selection range and is closest to the start of removed range.\n\t\tconst selectionRange = this._document.getNearestSelectionRange( positionCandidate );\n\n\t\t// Remove the old selection range before preparing and adding new selection range. This order is important,\n\t\t// because new range, in some cases, may intersect with old range (it depends on `getNearestSelectionRange()` result).\n\t\tconst index = this._ranges.indexOf( liveRange );\n\t\tthis._ranges.splice( index, 1 );\n\t\tliveRange.detach();\n\n\t\t// If nearest valid selection range has been found - add it in the place of old range.\n\t\tif ( selectionRange ) {\n\t\t\t// Check the range, convert it to live range, bind events, etc.\n\t\t\tconst newRange = this._prepareRange( selectionRange );\n\n\t\t\t// Add new range in the place of old range.\n\t\t\tthis._ranges.splice( index, 0, newRange );\n\t\t}\n\t\t// If nearest valid selection range cannot be found - just removing the old range is fine.\n\n\t\t// Fire an event informing about selection change.\n\t\tthis.fire( 'change:range', { directChange: false } );\n\t}\n}\n\n/**\n * @event change:attribute\n */\n\n// Helper function for {@link module:engine/model/documentselection~DocumentSelection#_updateAttributes}.\n//\n// It takes model item, checks whether it is a text node (or text proxy) and, if so, returns it's attributes. If not, returns `null`.\n//\n// @param {module:engine/model/item~Item|null} node\n// @returns {Boolean}\nfunction getAttrsIfCharacter( node ) {\n\tif ( node instanceof TextProxy || node instanceof Text ) {\n\t\treturn node.getAttributes();\n\t}\n\n\treturn null;\n}\n\n// Removes selection attributes from element which is not empty anymore.\nfunction clearAttributesStoredInElement( changes, batch, document ) {\n\t// Batch may not be passed to the document#change event in some tests.\n\t// See https://github.com/ckeditor/ckeditor5-engine/issues/1001#issuecomment-314202352\n\t// Ignore also transparent batches because they are... transparent.\n\tif ( !batch || batch.type == 'transparent' ) {\n\t\treturn;\n\t}\n\n\tconst changeParent = changes.range && changes.range.start.parent;\n\n\t// `changes.range` is not set in case of rename, root and marker operations.\n\t// None of them may lead to the element becoming non-empty.\n\tif ( !changeParent || changeParent.isEmpty ) {\n\t\treturn;\n\t}\n\n\tdocument.enqueueChanges( () => {\n\t\tconst storedAttributes = Array.from( changeParent.getAttributeKeys() ).filter( key => key.startsWith( storePrefix ) );\n\n\t\tfor ( const key of storedAttributes ) {\n\t\t\tbatch.removeAttribute( changeParent, key );\n\t\t}\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/documentselection.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/schema\n */\n\nimport Position from './position';\nimport Element from './element';\nimport Range from './range';\nimport DocumentSelection from './documentselection';\nimport clone from '@ckeditor/ckeditor5-utils/src/lib/lodash/clone';\nimport isArray from '@ckeditor/ckeditor5-utils/src/lib/lodash/isArray';\nimport isString from '@ckeditor/ckeditor5-utils/src/lib/lodash/isString';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Schema is a definition of the structure of the document. It allows to define which tree model items (element, text, etc.)\n * can be nested within which ones and which attributes can be applied to them. It's created during the run-time of the application,\n * typically by features. Also, the features can query the schema to learn what structure is allowed and act accordingly.\n *\n * For instance, if a feature wants to define that an attribute bold is allowed on the text it needs to register this rule like this:\n *\n *\t\teditor.document.schema.allow( '$text', 'bold' );\n *\n * Note: items prefixed with `$` are special group of items. By default, `Schema` defines three special items:\n *\n * * `$inline` represents all inline elements,\n * * `$text` is a sub-group of `$inline` and represents text nodes,\n * * `$block` represents block elements,\n * * `$root` represents default editing roots (those that allow only `$block`s inside them).\n *\n * When registering an item it's possible to tell that this item should inherit from some other existing item.\n * E.g. `p` can inherit from `$block`, so whenever given attribute is allowed on the `$block` it will automatically be\n * also allowed on the `p` element. By default, `$text` item already inherits from `$inline`.\n */\nexport default class Schema {\n\t/**\n\t * Creates Schema instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Names of elements which have \"object\" nature. This means that these\n\t\t * elements should be treated as whole, never merged, can be selected from outside, etc.\n\t\t * Just like images, placeholder widgets, etc.\n\t\t *\n\t\t * @member {Set.<String>} module:engine/model/schema~Schema#objects\n\t\t */\n\t\tthis.objects = new Set();\n\n\t\t/**\n\t\t * Names of elements to which editing operations should be limited.\n\t\t * For example, the <kbd>Enter</kbd> should not split such elements and\n\t\t * <kbd>Backspace</kbd> should not be able to leave or modify such elements.\n\t\t *\n\t\t * @member {Set.<String>} module:engine/model/schema~Schema#limits\n\t\t */\n\t\tthis.limits = new Set();\n\n\t\t/**\n\t\t * Schema items registered in the schema.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/model/schema~Schema#_items\n\t\t */\n\t\tthis._items = new Map();\n\n\t\t/**\n\t\t * Description of what entities are a base for given entity.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/model/schema~Schema#_extensionChains\n\t\t */\n\t\tthis._extensionChains = new Map();\n\n\t\t// Register some default abstract entities.\n\t\tthis.registerItem( '$root' );\n\t\tthis.registerItem( '$block' );\n\t\tthis.registerItem( '$inline' );\n\t\tthis.registerItem( '$text', '$inline' );\n\n\t\tthis.allow( { name: '$block', inside: '$root' } );\n\t\tthis.allow( { name: '$inline', inside: '$block' } );\n\n\t\tthis.limits.add( '$root' );\n\n\t\t// TMP!\n\t\t// Create an \"all allowed\" context in the schema for processing the pasted content.\n\t\t// Read: https://github.com/ckeditor/ckeditor5-engine/issues/638#issuecomment-255086588\n\n\t\tthis.registerItem( '$clipboardHolder', '$root' );\n\t\tthis.allow( { name: '$inline', inside: '$clipboardHolder' } );\n\t}\n\n\t/**\n\t * Allows given query in the schema.\n\t *\n\t *\t\t// Allow text with bold attribute in all P elements.\n\t *\t\tschema.registerItem( 'p', '$block' );\n\t *\t\tschema.allow( { name: '$text', attributes: 'bold', inside: 'p' } );\n\t *\n\t *\t\t// Allow header in Ps that are in DIVs\n\t *\t\tschema.registerItem( 'header', '$block' );\n\t *\t\tschema.registerItem( 'div', '$block' );\n\t *\t\tschema.allow( { name: 'header', inside: 'div p' } ); // inside: [ 'div', 'p' ] would also work.\n\t *\n\t * @param {module:engine/model/schema~SchemaQuery} query Allowed query.\n\t */\n\tallow( query ) {\n\t\tthis._getItem( query.name ).allow( Schema._normalizeQueryPath( query.inside ), query.attributes );\n\t}\n\n\t/**\n\t * Disallows given query in the schema.\n\t *\n\t * @see #allow\n\t * @param {module:engine/model/schema~SchemaQuery} query Disallowed query.\n\t */\n\tdisallow( query ) {\n\t\tthis._getItem( query.name ).disallow( Schema._normalizeQueryPath( query.inside ), query.attributes );\n\t}\n\n\t/**\n\t * Makes a requirement in schema that entity represented by given item has to have given set of attributes. Some\n\t * elements in the model might require some attributes to be set. If multiple sets of attributes are required it\n\t * is enough that the entity fulfills only one set.\n\t *\n\t *\t\t// \"a\" element must either have \"href\" attribute or \"name\" attribute\n\t *\t\tschema.requireAttributes( 'a', [ 'href' ] );\n\t *\t\tschema.requireAttributes( 'a', [ 'name' ] );\n\t *\t\t// \"img\" element must have both \"src\" and \"alt\" attributes\n\t *\t\tschema.requireAttributes( 'img', [ 'src', 'alt' ] );\n\t *\n\t * @param {String} name Entity name.\n\t * @param {Array.<String>} attributes Attributes that has to be set on the entity to make it valid.\n\t */\n\trequireAttributes( name, attributes ) {\n\t\tthis._getItem( name ).requireAttributes( attributes );\n\t}\n\n\t/**\n\t * Checks whether given query is allowed in schema.\n\t *\n\t *\t\t// Check whether bold text is allowed in header element.\n\t *\t\tlet query = {\n\t *\t\t\tname: '$text',\n\t *\t\t\tattributes: 'bold',\n\t *\t\t\tinside: 'header'\n\t *\t\t};\n\t *\t\tif ( schema.check( query ) ) { ... }\n\t *\n\t *\t\t// Check whether bold and italic text can be placed at caret position.\n\t *\t\tlet caretPos = editor.document.selection.getFirstPosition();\n\t *\t\tlet query = {\n\t *\t\t\tname: '$text',\n\t *\t\t\tattributes: [ 'bold', 'italic' ],\n\t *\t\t\tinside: caretPos\n\t *\t\t};\n\t *\t\tif ( schema.check( query ) ) { ... }\n\t *\n\t *\t\t// Check whether image with alt, src and title is allowed in given elements path.\n\t *\t\tlet quoteElement = new Element( 'quote' );\n\t *\t\tlet query = {\n\t *\t\t\tname: 'img',\n\t *\t\t\tattributes: [ 'alt', 'src', 'title' ],\n\t *\t\t\t// It is possible to mix strings with elements.\n\t *\t\t\t// Query will check whether \"img\" can be inside \"quoteElement\" that is inside a block element.\n\t *\t\t\tinside: [ '$block', quoteElement ]\n\t *\t\t};\n\t *\t\tif ( schema.check( query ) ) { ... }\n\t *\n\t * @param {module:engine/model/schema~SchemaQuery} query Query to check.\n\t * @returns {Boolean} `true` if given query is allowed in schema, `false` otherwise.\n\t */\n\tcheck( query ) {\n\t\tif ( !this.hasItem( query.name ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If attributes property is a string or undefined, wrap it in an array for easier processing.\n\t\tif ( !isArray( query.attributes ) ) {\n\t\t\tquery.attributes = [ query.attributes ];\n\t\t} else if ( query.attributes.length === 0 ) {\n\t\t\t// To simplify algorithms, when a SchemaItem path is added \"without\" attribute, it is added with\n\t\t\t// attribute equal to undefined. This means that algorithms can work the same way for specified attributes\n\t\t\t// and no-atrtibutes, but we have to fill empty array with \"fake\" undefined value for algorithms reasons.\n\t\t\tquery.attributes.push( undefined );\n\t\t}\n\n\t\t// Normalize the path to an array of strings.\n\t\tconst path = Schema._normalizeQueryPath( query.inside );\n\n\t\t// Get extension chain of given item and retrieve all schema items that are extended by given item.\n\t\tconst schemaItems = this._extensionChains.get( query.name ).map( name => {\n\t\t\treturn this._getItem( name );\n\t\t} );\n\n\t\t// First check if the query meets at required attributes for this item.\n\t\tif ( !this._getItem( query.name )._checkRequiredAttributes( query.attributes ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If there is matching disallow path, this query is not valid with schema.\n\t\tfor ( const attribute of query.attributes ) {\n\t\t\tfor ( const schemaItem of schemaItems ) {\n\t\t\t\tif ( schemaItem._hasMatchingPath( 'disallow', path, attribute ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// At this point, the query is not disallowed.\n\t\t// If there are correct allow paths that match the query, this query is valid with schema.\n\t\t// Since we are supporting multiple attributes, we have to make sure that if attributes are set,\n\t\t// we have allowed paths for all of them.\n\t\t// Keep in mind that if the query has no attributes, query.attribute was converted to an array\n\t\t// with a single `undefined` value. This fits the algorithm well.\n\t\tfor ( const attribute of query.attributes ) {\n\t\t\t// Skip all attributes that are stored in elements.\n\t\t\t// This isn't perfect solution but we have to deal with it for now.\n\t\t\t// `attribute` may have `undefined` value.\n\t\t\tif ( attribute && DocumentSelection._isStoreAttributeKey( attribute ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet matched = false;\n\n\t\t\tfor ( const schemaItem of schemaItems ) {\n\t\t\t\tif ( schemaItem._hasMatchingPath( 'allow', path, attribute ) ) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The attribute has not been matched, so it is not allowed by any schema item.\n\t\t\t// The query is disallowed.\n\t\t\tif ( !matched ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether there is an item registered under given name in schema.\n\t *\n\t * @param itemName\n\t * @returns {Boolean}\n\t */\n\thasItem( itemName ) {\n\t\treturn this._items.has( itemName );\n\t}\n\n\t/**\n\t * Registers given item name in schema.\n\t *\n\t *\t\t// Register P element that should be treated like all block elements.\n\t *\t\tschema.registerItem( 'p', '$block' );\n\t *\n\t * @param {String} itemName Name to register.\n\t * @param [isExtending] If set, new item will extend item with given name.\n\t */\n\tregisterItem( itemName, isExtending ) {\n\t\tif ( this.hasItem( itemName ) ) {\n\t\t\t/**\n\t\t\t * Item with specified name already exists in schema.\n\t\t\t *\n\t\t\t * @error model-schema-item-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-schema-item-exists: Item with specified name already exists in schema.' );\n\t\t}\n\n\t\tif ( !!isExtending && !this.hasItem( isExtending ) ) {\n\t\t\tthrow new CKEditorError( 'model-schema-no-item: Item with specified name does not exist in schema.' );\n\t\t}\n\n\t\t// Create new SchemaItem and add it to the items store.\n\t\tthis._items.set( itemName, new SchemaItem( this ) );\n\n\t\t// Create an extension chain.\n\t\t// Extension chain has all item names that should be checked when that item is on path to check.\n\t\t// This simply means, that if item is not extending anything, it should have only itself in it's extension chain.\n\t\t// Since extending is not dynamic, we can simply get extension chain of extended item and expand it with registered name,\n\t\t// if the registered item is extending something.\n\t\tconst chain = this.hasItem( isExtending ) ? this._extensionChains.get( isExtending ).concat( itemName ) : [ itemName ];\n\t\tthis._extensionChains.set( itemName, chain );\n\t}\n\n\t/**\n\t * Checks whether item of given name is extending item of another given name.\n\t *\n\t * @param {String} childItemName Name of the child item.\n\t * @param {String} parentItemName Name of the parent item.\n\t * @returns {Boolean} `true` if child item extends parent item, `false` otherwise.\n\t */\n\titemExtends( childItemName, parentItemName ) {\n\t\tif ( !this.hasItem( childItemName ) || !this.hasItem( parentItemName ) ) {\n\t\t\tthrow new CKEditorError( 'model-schema-no-item: Item with specified name does not exist in schema.' );\n\t\t}\n\n\t\tconst chain = this._extensionChains.get( childItemName );\n\n\t\treturn chain.some( itemName => itemName == parentItemName );\n\t}\n\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 {module:engine/model/selection~Selection} selection Selection which will be checked.\n\t * @param {String} attribute The name of the attribute to check.\n\t * @returns {Boolean}\n\t */\n\tcheckAttributeInSelection( selection, attribute ) {\n\t\tif ( selection.isCollapsed ) {\n\t\t\t// Check whether schema allows for a text with the attribute in the selection.\n\t\t\treturn this.check( { name: '$text', inside: selection.getFirstPosition(), attributes: attribute } );\n\t\t} else {\n\t\t\tconst ranges = selection.getRanges();\n\n\t\t\t// For all ranges, check nodes in them until you find a node that is allowed to have the attribute.\n\t\t\tfor ( const range of ranges ) {\n\t\t\t\tfor ( const value of range ) {\n\t\t\t\t\t// If returned item does not have name property, it is a TextFragment.\n\t\t\t\t\tconst name = value.item.name || '$text';\n\n\t\t\t\t\t// Attribute should be checked together with existing attributes.\n\t\t\t\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/1110.\n\t\t\t\t\tconst attributes = Array.from( value.item.getAttributeKeys() ).concat( attribute );\n\n\t\t\t\t\tif ( this.check( { name, inside: value.previousPosition, attributes } ) ) {\n\t\t\t\t\t\t// If we found a node that is allowed to have the attribute, return true.\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't found such node, return false.\n\t\treturn false;\n\t}\n\n\t/**\n\t * Transforms the given set ranges into a set of ranges where the given attribute is allowed (and can be applied).\n\t *\n\t * @param {Array.<module:engine/model/range~Range>} ranges Ranges to be validated.\n\t * @param {String} attribute The name of the attribute to check.\n\t * @returns {Array.<module:engine/model/range~Range>} Ranges in which the attribute is allowed.\n\t */\n\tgetValidRanges( ranges, attribute ) {\n\t\tconst validRanges = [];\n\n\t\tfor ( const range of ranges ) {\n\t\t\tlet last = range.start;\n\t\t\tlet from = range.start;\n\t\t\tconst to = range.end;\n\n\t\t\tfor ( const value of range.getWalker() ) {\n\t\t\t\tconst name = value.item.name || '$text';\n\t\t\t\tconst itemPosition = Position.createBefore( value.item );\n\n\t\t\t\tif ( !this.check( { name, inside: itemPosition, attributes: attribute } ) ) {\n\t\t\t\t\tif ( !from.isEqual( last ) ) {\n\t\t\t\t\t\tvalidRanges.push( new Range( from, last ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tfrom = value.nextPosition;\n\t\t\t\t}\n\n\t\t\t\tlast = value.nextPosition;\n\t\t\t}\n\n\t\t\tif ( from && !from.isEqual( to ) ) {\n\t\t\t\tvalidRanges.push( new Range( from, to ) );\n\t\t\t}\n\t\t}\n\n\t\treturn validRanges;\n\t}\n\n\t/**\n\t * Returns the lowest {@link module:engine/model/schema~Schema#limits limit element} containing the entire\n\t * selection or the root otherwise.\n\t *\n\t * @param {module:engine/model/selection~Selection} selection Selection which returns the common ancestor.\n\t * @returns {module:engine/model/element~Element}\n\t */\n\tgetLimitElement( selection ) {\n\t\t// Find the common ancestor for all selection's ranges.\n\t\tlet element = Array.from( selection.getRanges() )\n\t\t\t.reduce( ( node, range ) => {\n\t\t\t\tif ( !node ) {\n\t\t\t\t\treturn range.getCommonAncestor();\n\t\t\t\t}\n\n\t\t\t\treturn node.getCommonAncestor( range.getCommonAncestor() );\n\t\t\t}, null );\n\n\t\twhile ( !this.limits.has( element.name ) ) {\n\t\t\tif ( element.parent ) {\n\t\t\t\telement = element.parent;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn element;\n\t}\n\n\t/**\n\t * Removes disallowed by {@link module:engine/model/schema~Schema schema} attributes from given nodes.\n\t * When {@link module:engine/model/batch~Batch batch} parameter is provided then attributes will be removed\n\t * using that batch, by creating {@link module:engine/model/delta/attributedelta~AttributeDelta attribute deltas}.\n\t * Otherwise, attributes will be removed directly from provided nodes using {@link module:engine/model/node~Node node} API.\n\t *\n\t * @param {Iterable.<module:engine/model/node~Node>} nodes Nodes that will be filtered.\n\t * @param {module:engine/model/schema~SchemaPath} inside Path inside which schema will be checked.\n\t * @param {module:engine/model/batch~Batch} [batch] Batch to which the deltas will be added.\n\t */\n\tremoveDisallowedAttributes( nodes, inside, batch ) {\n\t\tfor ( const node of nodes ) {\n\t\t\tconst name = node.is( 'text' ) ? '$text' : node.name;\n\t\t\tconst attributes = Array.from( node.getAttributeKeys() );\n\t\t\tconst queryPath = Schema._normalizeQueryPath( inside );\n\n\t\t\t// When node with attributes is not allowed in current position.\n\t\t\tif ( !this.check( { name, attributes, inside: queryPath } ) ) {\n\t\t\t\t// Let's remove attributes one by one.\n\t\t\t\t// TODO: this should be improved to check all combination of attributes.\n\t\t\t\tfor ( const attribute of node.getAttributeKeys() ) {\n\t\t\t\t\tif ( !this.check( { name, attributes: attribute, inside: queryPath } ) ) {\n\t\t\t\t\t\tif ( batch ) {\n\t\t\t\t\t\t\tbatch.removeAttribute( node, attribute );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnode.removeAttribute( attribute );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( node.is( 'element' ) ) {\n\t\t\t\tthis.removeDisallowedAttributes( node.getChildren(), queryPath.concat( node.name ), batch );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns {@link module:engine/model/schema~SchemaItem schema item} that was registered in the schema under given name.\n\t * If item has not been found, throws error.\n\t *\n\t * @private\n\t * @param {String} itemName Name to look for in schema.\n\t * @returns {module:engine/model/schema~SchemaItem} Schema item registered under given name.\n\t */\n\t_getItem( itemName ) {\n\t\tif ( !this.hasItem( itemName ) ) {\n\t\t\tthrow new CKEditorError( 'model-schema-no-item: Item with specified name does not exist in schema.' );\n\t\t}\n\n\t\treturn this._items.get( itemName );\n\t}\n\n\t/**\n\t * Normalizes a path to an entity by converting it from {@link module:engine/model/schema~SchemaPath} to an array of strings.\n\t *\n\t * @protected\n\t * @param {module:engine/model/schema~SchemaPath} path Path to normalize.\n\t * @returns {Array.<String>} Normalized path.\n\t */\n\tstatic _normalizeQueryPath( path ) {\n\t\tlet normalized = [];\n\n\t\tif ( isArray( path ) ) {\n\t\t\tfor ( const pathItem of path ) {\n\t\t\t\tif ( pathItem instanceof Element ) {\n\t\t\t\t\tnormalized.push( pathItem.name );\n\t\t\t\t} else if ( isString( pathItem ) ) {\n\t\t\t\t\tnormalized.push( pathItem );\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( path instanceof Position ) {\n\t\t\tlet parent = path.parent;\n\n\t\t\twhile ( parent !== null ) {\n\t\t\t\tnormalized.push( parent.name );\n\t\t\t\tparent = parent.parent;\n\t\t\t}\n\n\t\t\tnormalized.reverse();\n\t\t} else if ( isString( path ) ) {\n\t\t\tnormalized = path.split( ' ' );\n\t\t}\n\n\t\treturn normalized;\n\t}\n}\n\n/**\n * SchemaItem is a singular registry item in {@link module:engine/model/schema~Schema} that groups and holds allow/disallow rules for\n * one entity. This class is used internally in {@link module:engine/model/schema~Schema} and should not be used outside it.\n *\n * @see module:engine/model/schema~Schema\n * @protected\n */\nexport class SchemaItem {\n\t/**\n\t * Creates SchemaItem instance.\n\t *\n\t * @param {module:engine/model/schema~Schema} schema Schema instance that owns this item.\n\t */\n\tconstructor( schema ) {\n\t\t/**\n\t\t * Schema instance that owns this item.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/schema~Schema} module:engine/model/schema~SchemaItem#_schema\n\t\t */\n\t\tthis._schema = schema;\n\n\t\t/**\n\t\t * Paths in which the entity, represented by this item, is allowed.\n\t\t *\n\t\t * @private\n\t\t * @member {Array} module:engine/model/schema~SchemaItem#_allowed\n\t\t */\n\t\tthis._allowed = [];\n\n\t\t/**\n\t\t * Paths in which the entity, represented by this item, is disallowed.\n\t\t *\n\t\t * @private\n\t\t * @member {Array} module:engine/model/schema~SchemaItem#_disallowed\n\t\t */\n\t\tthis._disallowed = [];\n\n\t\t/**\n\t\t * Attributes that are required by the entity represented by this item.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array} module:engine/model/schema~SchemaItem#_requiredAttributes\n\t\t */\n\t\tthis._requiredAttributes = [];\n\t}\n\n\t/**\n\t * Allows entity, represented by this item, to be in given path.\n\t *\n\t * @param {Array.<String>} path Path in which entity is allowed.\n\t * @param {Array.<String>|String} [attributes] If set, this path will be used only for entities that have attribute(s) with this key.\n\t */\n\tallow( path, attributes ) {\n\t\tthis._addPath( '_allowed', path, attributes );\n\t}\n\n\t/**\n\t * Disallows entity, represented by this item, to be in given path.\n\t *\n\t * @param {Array.<String>} path Path in which entity is disallowed.\n\t * @param {Array.<String>|String} [attributes] If set, this path will be used only for entities that have an attribute(s) with this key.\n\t */\n\tdisallow( path, attributes ) {\n\t\tthis._addPath( '_disallowed', path, attributes );\n\t}\n\n\t/**\n\t * Specifies that the entity, to be valid, requires given attributes set. It is possible to register multiple\n\t * different attributes set. If there are more than one attributes set required, the entity will be valid if\n\t * at least one of them is fulfilled.\n\t *\n\t * @param {Array.<String>} attributes Attributes that has to be set on the entity to make it valid.\n\t */\n\trequireAttributes( attributes ) {\n\t\tthis._requiredAttributes.push( attributes );\n\t}\n\n\t/**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @returns {Object} Clone of this object with the parent property replaced with its name.\n\t */\n\ttoJSON() {\n\t\tconst json = clone( this );\n\n\t\t// Due to circular references we need to remove parent reference.\n\t\tjson._schema = '[model.Schema]';\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Adds path to the SchemaItem instance.\n\t *\n\t * @private\n\t * @param {String} member Name of the array member into which the path will be added. Possible values are `_allowed` or `_disallowed`.\n\t * @param {Array.<String>} path Path to add.\n\t * @param {Array.<String>|String} [attributes] If set, this path will be used only for entities that have attribute(s) with this key.\n\t */\n\t_addPath( member, path, attributes ) {\n\t\tpath = path.slice();\n\n\t\tif ( !isArray( attributes ) ) {\n\t\t\tattributes = [ attributes ];\n\t\t}\n\n\t\tfor ( const attribute of attributes ) {\n\t\t\tthis[ member ].push( { path, attribute } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns all paths of given type that were previously registered in the item.\n\t *\n\t * @private\n\t * @param {String} type Paths' type. Possible values are `allow` or `disallow`.\n\t * @param {String} [attribute] If set, only paths registered for given attribute will be returned.\n\t * @returns {Array} Paths registered in the item.\n\t */\n\t_getPaths( type, attribute ) {\n\t\tconst source = type === 'allow' ? this._allowed : this._disallowed;\n\t\tconst paths = [];\n\n\t\tfor ( const item of source ) {\n\t\t\tif ( item.attribute === attribute ) {\n\t\t\t\tpaths.push( item.path );\n\t\t\t}\n\t\t}\n\n\t\treturn paths;\n\t}\n\n\t/**\n\t * Checks whether given set of attributes fulfills required attributes of this item.\n\t *\n\t * @protected\n\t * @see module:engine/model/schema~SchemaItem#requireAttributes\n\t * @param {Array.<String>} attributesToCheck Attributes to check.\n\t * @returns {Boolean} `true` if given set or attributes fulfills required attributes, `false` otherwise.\n\t */\n\t_checkRequiredAttributes( attributesToCheck ) {\n\t\tlet found = true;\n\n\t\tfor ( const attributeSet of this._requiredAttributes ) {\n\t\t\tfound = true;\n\n\t\t\tfor ( const attribute of attributeSet ) {\n\t\t\t\tif ( attributesToCheck.indexOf( attribute ) == -1 ) {\n\t\t\t\t\tfound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( found ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn found;\n\t}\n\n\t/**\n\t * Checks whether this item has any registered path of given type that matches the provided path.\n\t *\n\t * @protected\n\t * @param {String} type Paths' type. Possible values are `allow` or `disallow`.\n\t * @param {Array.<String>} pathToCheck Path to check.\n\t * @param {String} [attribute] If set, only paths registered for given attribute will be checked.\n\t * @returns {Boolean} `true` if item has any registered matching path, `false` otherwise.\n\t */\n\t_hasMatchingPath( type, pathToCheck, attribute ) {\n\t\tconst registeredPaths = this._getPaths( type, attribute );\n\n\t\tfor ( const registeredPathPath of registeredPaths ) {\n\t\t\tif ( matchPaths( this._schema, pathToCheck, registeredPathPath ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\n/**\n * Object with query used by {@link module:engine/model/schema~Schema} to query schema or add allow/disallow rules to schema.\n *\n * @typedef {Object} module:engine/model/schema~SchemaQuery\n * @property {String} name Entity name.\n * @property {module:engine/model/schema~SchemaPath} inside Path inside which the entity is placed.\n * @property {Array.<String>|String} [attributes] If set, the query applies only to entities that has attribute(s) with given key.\n */\n\n/**\n * Path to an entity, begins from the top-most ancestor. Can be passed in multiple formats. Internally, normalized to\n * an array of strings. If string is passed, entities from the path should be divided by ` ` (space character). If\n * an array is passed, unrecognized items are skipped. If position is passed, it is assumed that the entity is at given position.\n *\n * @typedef {String|Array.<String|module:engine/model/element~Element>|module:engine/model/position~Position}\n * module:engine/model/schema~SchemaPath\n */\n\n// Checks whether the given pathToCheck and registeredPath right ends match.\n//\n// pathToCheck: C, D\n// registeredPath: A, B, C, D\n// result: OK\n//\n// pathToCheck: A, B, C\n// registeredPath: A, B, C, D\n// result: NOK\n//\n// Note when matching paths, element extension chains (inheritance) are taken into consideration.\n//\n// @param {Schema} schema\n// @param {Array.<String>} pathToCheck\n// @param {Array.<String>} registeredPath\nfunction matchPaths( schema, pathToCheck, registeredPath ) {\n\t// Start checking from the right end of both tables.\n\tlet registeredPathIndex = registeredPath.length - 1;\n\tlet pathToCheckIndex = pathToCheck.length - 1;\n\n\t// And finish once reaching an end of the shorter table.\n\twhile ( registeredPathIndex >= 0 && pathToCheckIndex >= 0 ) {\n\t\tconst checkName = pathToCheck[ pathToCheckIndex ];\n\n\t\t// Fail when checking a path which contains element which aren't even registered to the schema.\n\t\tif ( !schema.hasItem( checkName ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst extChain = schema._extensionChains.get( checkName );\n\n\t\tif ( extChain.includes( registeredPath[ registeredPathIndex ] ) ) {\n\t\t\tregisteredPathIndex--;\n\t\t\tpathToCheckIndex--;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Item with specified name does not exist in schema.\n *\n * @error model-schema-no-item\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/schema.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/markercollection\n */\n\nimport LiveRange from './liverange';\nimport Position from './position';\nimport Range from './range';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Creates, stores and manages {@link ~Marker markers}.\n *\n * Markers are created by {@link ~MarkerCollection#set setting} a name for a {@link module:engine/model/liverange~LiveRange live range}\n * in `MarkerCollection`. 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`.\n *\n * Since markers are based on {@link module:engine/model/liverange~LiveRange live ranges}, for efficiency reasons, it's\n * best to create and keep at least markers as possible.\n */\nexport default class MarkerCollection {\n\t/**\n\t * Creates a markers collection.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Stores {@link ~Marker markers} added to the collection.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} #_markers\n\t\t */\n\t\tthis._markers = new Map();\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link ~Marker markers} added to the collection.\n\t *\n\t * @returns {Iterator}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._markers.values();\n\t}\n\n\t/**\n\t * Checks if marker with given `markerName` is in the collection.\n\t *\n\t * @param {String} markerName Marker name.\n\t * @returns {Boolean} `true` if marker with given `markerName` is in the collection, `false` otherwise.\n\t */\n\thas( markerName ) {\n\t\treturn this._markers.has( markerName );\n\t}\n\n\t/**\n\t * Returns {@link ~Marker marker} with given `markerName`.\n\t *\n\t * @param {String} markerName Name of marker to get.\n\t * @returns {module:engine/model/markercollection~Marker|null} 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\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~Range range}.\n\t *\n\t * If `MarkerCollection` already had a marker with given name (or {@link ~Marker marker} was passed) and the range to\n\t * set is different, the marker in collection is removed and then new marker is added. If the range was same, nothing\n\t * happens and `false` is returned.\n\t *\n\t * @fires module:engine/model/markercollection~MarkerCollection#event:add\n\t * @fires module:engine/model/markercollection~MarkerCollection#event:remove\n\t * @param {String|module:engine/model/markercollection~Marker} markerOrName Name of marker to add or Marker instance to update.\n\t * @param {module:engine/model/range~Range} range Marker range.\n\t * @returns {module:engine/model/markercollection~Marker} `Marker` instance added to the collection.\n\t */\n\tset( markerOrName, range ) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst oldMarker = this._markers.get( markerName );\n\n\t\tif ( oldMarker ) {\n\t\t\tconst oldRange = oldMarker.getRange();\n\n\t\t\tif ( oldRange.isEqual( range ) ) {\n\t\t\t\treturn oldMarker;\n\t\t\t}\n\n\t\t\tthis.remove( markerName );\n\t\t}\n\n\t\tconst liveRange = LiveRange.createFromRange( range );\n\t\tconst marker = new Marker( markerName, liveRange );\n\n\t\tthis._markers.set( markerName, marker );\n\t\tthis.fire( 'add:' + markerName, marker );\n\n\t\treturn marker;\n\t}\n\n\t/**\n\t * Removes given {@link ~Marker marker} or a marker with given name from the `MarkerCollection`.\n\t *\n\t * @param {String} markerOrName Marker or name of a marker to remove.\n\t * @returns {Boolean} `true` if marker was found and removed, `false` otherwise.\n\t */\n\tremove( markerOrName ) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst oldMarker = this._markers.get( markerName );\n\n\t\tif ( oldMarker ) {\n\t\t\tthis._markers.delete( markerName );\n\t\t\tthis.fire( 'remove:' + markerName, oldMarker );\n\n\t\t\tthis._destroyMarker( oldMarker );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns iterator that iterates over all markers, which ranges contain given {@link module:engine/model/position~Position position}.\n\t *\n\t * @param {module:engine/model/position~Position} position\n\t * @returns {Iterator.<module:engine/model/markercollection~Marker>}\n\t */\n\t* getMarkersAtPosition( position ) {\n\t\tfor ( const marker of this ) {\n\t\t\tif ( marker.getRange().containsPosition( position ) ) {\n\t\t\t\tyield marker;\n\t\t\t}\n\t\t}\n\t}\n\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() ) {\n\t\t\tthis._destroyMarker( marker );\n\t\t}\n\n\t\tthis._markers = null;\n\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Iterates over all markers that starts with given `prefix`.\n\t *\n\t *\t\tconst markerFooA = markersCollection.set( 'foo:a', rangeFooA );\n\t *\t\tconst markerFooB = markersCollection.set( 'foo:b', rangeFooB );\n\t *\t\tconst markerBarA = markersCollection.set( 'bar:a', rangeBarA );\n\t *\t\tconst markerFooBarA = markersCollection.set( 'foobar:a', rangeFooBarA );\n\t *\t\tArray.from( markersCollection.getMarkersGroup( 'foo' ) ); // [ markerFooA, markerFooB ]\n\t *\t\tArray.from( markersCollection.getMarkersGroup( 'a' ) ); // []\n\t *\n\t * @param prefix\n\t * @returns {Iterator.<module:engine/model/markercollection~Marker>}\n\t */\n\t* getMarkersGroup( prefix ) {\n\t\tfor ( const marker of this._markers.values() ) {\n\t\t\tif ( marker.name.startsWith( prefix + ':' ) ) {\n\t\t\t\tyield marker;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the marker.\n\t *\n\t * @private\n\t * @param {module:engine/model/markercollection~Marker} marker Marker to destroy.\n\t */\n\t_destroyMarker( marker ) {\n\t\tmarker.stopListening();\n\t\tmarker._liveRange.detach();\n\t\tmarker._liveRange = null;\n\t}\n\n\t/**\n\t * Fired whenever marker is added to `MarkerCollection`.\n\t *\n\t * @event add\n\t * @param {module:engine/model/markercollection~Marker} The added marker.\n\t */\n\n\t/**\n\t * Fired whenever marker is removed from `MarkerCollection`.\n\t *\n\t * @event remove\n\t * @param {module:engine/model/markercollection~Marker} marker The removed marker.\n\t */\n}\n\nmix( MarkerCollection, EmitterMixin );\n\n/**\n * `Marker` is a continuous parts of model (like a range), is named and represent some kind of information about marked\n * part of model document. In contrary to {@link module:engine/model/node~Node nodes}, which are building blocks of\n * model document tree, markers are not stored directly in document tree. 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 characterised 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 * Since markers are based on {@link module:engine/model/liverange~LiveRange live ranges}, for efficiency reasons, it's\n * best to create and keep at least markers as possible.\n *\n * Markers can be converted to view by adding appropriate converters for\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:addMarker} and\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:removeMarker}\n * events, or by building converters for {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}\n * using {@link module:engine/conversion/buildmodelconverter~buildModelConverter model converter builder}.\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 * `Marker` instances are created and destroyed only by {@link ~MarkerCollection MarkerCollection}.\n */\nclass Marker {\n\t/**\n\t * Creates a marker instance.\n\t *\n\t * @param {String} name Marker name.\n\t * @param {module:engine/model/liverange~LiveRange} liveRange Range marked by the marker.\n\t */\n\tconstructor( name, liveRange ) {\n\t\t/**\n\t\t * Marker's name.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} #name\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Range marked by the marker.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:engine/model/liverange~LiveRange} #_liveRange\n\t\t */\n\t\tthis._liveRange = liveRange;\n\n\t\t// Delegating does not work with namespaces. Alternatively, we could delegate all events (using `*`).\n\t\tthis._liveRange.delegate( 'change:range' ).to( this );\n\t\tthis._liveRange.delegate( 'change:content' ).to( this );\n\t}\n\n\t/**\n\t * Returns current marker start position.\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tgetStart() {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );\n\t\t}\n\n\t\treturn Position.createFromPosition( this._liveRange.start );\n\t}\n\n\t/**\n\t * Returns current marker end position.\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tgetEnd() {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );\n\t\t}\n\n\t\treturn Position.createFromPosition( this._liveRange.end );\n\t}\n\n\t/**\n\t * Returns a range that represents current state of marker.\n\t *\n\t * Keep in mind that returned value is a {@link module:engine/model/range~Range Range}, not a\n\t * {@link module:engine/model/liverange~LiveRange LiveRange}. 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\t * @returns {module:engine/model/range~Range}\n\t */\n\tgetRange() {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );\n\t\t}\n\n\t\treturn Range.createFromRange( this._liveRange );\n\t}\n\n\t/**\n\t * Fired whenever {@link ~Marker#_liveRange marker range} is changed due to changes on {@link module:engine/model/document~Document}.\n\t * This is a delegated {@link module:engine/model/liverange~LiveRange#event:change:range LiveRange change:range event}.\n\t *\n\t * When marker is removed from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection},\n\t * all event listeners listening to it should be removed. It is best to do it on\n\t * {@link module:engine/model/markercollection~MarkerCollection#event:remove MarkerCollection remove event}.\n\t *\n\t * @see module:engine/model/liverange~LiveRange#event:change:range\n\t * @event change:range\n\t * @param {module:engine/model/range~Range} oldRange\n\t * @param {Object} data\n\t */\n\n\t/**\n\t * Fired whenever change on {@link module:engine/model/document~Document} is done inside {@link ~Marker#_liveRange marker range}.\n\t * This is a delegated {@link module:engine/model/liverange~LiveRange#event:change:content LiveRange change:content event}.\n\t *\n\t * When marker is removed from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection},\n\t * all event listeners listening to it should be removed. It is best to do it on\n\t * {@link module:engine/model/markercollection~MarkerCollection#event:remove MarkerCollection remove event}.\n\t *\n\t * @see module:engine/model/liverange~LiveRange#event:change:content\n\t * @event change:content\n\t * @param {module:engine/model/range~Range} oldRange\n\t * @param {Object} data\n\t */\n}\n\nmix( Marker, EmitterMixin );\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\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/markercollection.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/document\n */\n\n// Load all basic deltas and transformations, they register themselves.\nimport './delta/basic-deltas';\nimport './delta/basic-transformations';\n\nimport Range from './range';\nimport Position from './position';\nimport RootElement from './rootelement';\nimport Batch from './batch';\nimport History from './history';\nimport DocumentSelection from './documentselection';\nimport Schema from './schema';\nimport TreeWalker from './treewalker';\nimport MarkerCollection from './markercollection';\nimport deltaTransform from './delta/transform';\nimport clone from '@ckeditor/ckeditor5-utils/src/lib/lodash/clone';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport { isInsideSurrogatePair, isInsideCombinedSymbol } from '@ckeditor/ckeditor5-utils/src/unicode';\n\nconst graveyardName = '$graveyard';\n\n/**\n * Document tree model describes all editable data in the editor. It may contain multiple\n * {@link module:engine/model/document~Document#roots root elements}, for example if the editor have multiple editable areas,\n * each area will be represented by the separate root.\n *\n * All changes in the document are done by {@link module:engine/model/operation/operation~Operation operations}. To create operations in\n * a simple way, use the {@link module:engine/model/batch~Batch} API, for example:\n *\n *\t\tdoc.batch().insert( position, nodes ).split( otherPosition );\n *\n * @see module:engine/model/document~Document#batch\n * @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class Document {\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() {\n\t\t/**\n\t\t * Document version. It starts from `0` and every operation increases the version number. It is used to ensure that\n\t\t * operations are applied on the proper document version.\n\t\t * If the {@link module:engine/model/operation/operation~Operation#baseVersion} will not match document version the\n\t\t * {@link module:utils/ckeditorerror~CKEditorError model-document-applyOperation-wrong-version} error is thrown.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.version = 0;\n\n\t\t/**\n\t\t * Schema for this document.\n\t\t *\n\t\t * @member {module:engine/model/schema~Schema}\n\t\t */\n\t\tthis.schema = new Schema();\n\n\t\t/**\n\t\t * Document's history.\n\t\t *\n\t\t * **Note:** Be aware that deltas applied to the document might get removed or changed.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/history~History}\n\t\t */\n\t\tthis.history = new History( this );\n\n\t\t/**\n\t\t * Document's markers' collection.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/markercollection~MarkerCollection}\n\t\t */\n\t\tthis.markers = new MarkerCollection();\n\n\t\t/**\n\t\t * Selection done on this document.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/documentselection~DocumentSelection}\n\t\t */\n\t\tthis.selection = new DocumentSelection( this );\n\n\t\t/**\n\t\t * Array of pending changes. See: {@link #enqueueChanges}.\n\t\t *\n\t\t * @private\n\t\t * @member {Array.<Function>}\n\t\t */\n\t\tthis._pendingChanges = [];\n\n\t\t/**\n\t\t * List of roots that are owned and managed by this document. Use {@link #createRoot} and\n\t\t * {@link #getRoot} to manipulate it.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Map}\n\t\t */\n\t\tthis.roots = new Map();\n\n\t\t// Add events that will ensure selection correctness.\n\t\tthis.selection.on( 'change:range', () => {\n\t\t\tfor ( const range of this.selection.getRanges() ) {\n\t\t\t\tif ( !this._validateSelectionRange( range ) ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Range from {@link module:engine/model/documentselection~DocumentSelection document selection}\n\t\t\t\t\t * starts or ends at incorrect position.\n\t\t\t\t\t *\n\t\t\t\t\t * @error document-selection-wrong-position\n\t\t\t\t\t * @param {module:engine/model/range~Range} range\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'document-selection-wrong-position: ' +\n\t\t\t\t\t\t'Range from document selection starts or ends at incorrect position.', { range } );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Graveyard tree root. Document always have a graveyard root, which stores removed nodes.\n\t\tthis.createRoot( '$root', graveyardName );\n\t}\n\n\t/**\n\t * Graveyard tree root. Document always have a graveyard root, which stores removed nodes.\n\t *\n\t * @readonly\n\t * @member {module:engine/model/rootelement~RootElement}\n\t */\n\tget graveyard() {\n\t\treturn this.getRoot( graveyardName );\n\t}\n\n\t/**\n\t * This is the entry point for all document changes. All changes on the document are done using\n\t * {@link module:engine/model/operation/operation~Operation operations}. To create operations in the simple way use the\n\t * {@link module:engine/model/batch~Batch} API available via {@link #batch} method.\n\t *\n\t * @fires event:change\n\t * @param {module:engine/model/operation/operation~Operation} operation Operation to be applied.\n\t */\n\tapplyOperation( operation ) {\n\t\tif ( operation.baseVersion !== this.version ) {\n\t\t\t/**\n\t\t\t * Only operations with matching versions can be applied.\n\t\t\t *\n\t\t\t * @error document-applyOperation-wrong-version\n\t\t\t * @param {module:engine/model/operation/operation~Operation} operation\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-document-applyOperation-wrong-version: Only operations with matching versions can be applied.',\n\t\t\t\t{ operation } );\n\t\t}\n\n\t\tconst changes = operation._execute();\n\n\t\tthis.version++;\n\n\t\tthis.history.addDelta( operation.delta );\n\n\t\tthis.fire( 'change', operation.type, changes, operation.delta.batch, operation.delta.type );\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/batch~Batch} instance which allows to change the document.\n\t *\n\t * @param {String} [type] Batch type. See {@link module:engine/model/batch~Batch#type}.\n\t * @returns {module:engine/model/batch~Batch} Batch instance.\n\t */\n\tbatch( type ) {\n\t\treturn new Batch( this, type );\n\t}\n\n\t/**\n\t * Creates a new top-level root.\n\t *\n\t * @param {String} [elementName='$root'] Element name. Defaults to `'$root'` which also have\n\t * some basic schema defined (`$block`s are allowed inside the `$root`). Make sure to define a proper\n\t * schema if you use a different name.\n\t * @param {String} [rootName='main'] Unique root name.\n\t * @returns {module:engine/model/rootelement~RootElement} Created root.\n\t */\n\tcreateRoot( elementName = '$root', rootName = 'main' ) {\n\t\tif ( this.roots.has( rootName ) ) {\n\t\t\t/**\n\t\t\t * Root with specified name already exists.\n\t\t\t *\n\t\t\t * @error model-document-createRoot-name-exists\n\t\t\t * @param {module:engine/model/document~Document} doc\n\t\t\t * @param {String} name\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-document-createRoot-name-exists: Root with specified name already exists.',\n\t\t\t\t{ name: rootName }\n\t\t\t);\n\t\t}\n\n\t\tconst root = new RootElement( this, elementName, rootName );\n\t\tthis.roots.set( rootName, root );\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * Removes all events listeners set by document instance.\n\t */\n\tdestroy() {\n\t\tthis.selection.destroy();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Enqueues document changes. Any changes to be done on document (mostly using {@link #batch}\n\t * should be placed in the queued callback. If no other plugin is changing document at the moment, the callback will be\n\t * called immediately. Otherwise it will wait for all previously queued changes to finish happening. This way\n\t * queued callback will not interrupt other callbacks.\n\t *\n\t * When all queued changes are done {@link #event:changesDone} event is fired.\n\t *\n\t * @fires changesDone\n\t * @param {Function} callback Callback to enqueue.\n\t */\n\tenqueueChanges( callback ) {\n\t\tthis._pendingChanges.push( callback );\n\n\t\tif ( this._pendingChanges.length == 1 ) {\n\t\t\twhile ( this._pendingChanges.length ) {\n\t\t\t\tthis._pendingChanges[ 0 ]();\n\t\t\t\tthis._pendingChanges.shift();\n\t\t\t}\n\n\t\t\tthis.fire( 'changesDone' );\n\t\t}\n\t}\n\n\t/**\n\t * Returns top-level root by its name.\n\t *\n\t * @param {String} [name='main'] Unique root name.\n\t * @returns {module:engine/model/rootelement~RootElement} Root registered under given name.\n\t */\n\tgetRoot( name = 'main' ) {\n\t\tif ( !this.roots.has( name ) ) {\n\t\t\t/**\n\t\t\t * Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error model-document-getRoot-root-not-exist\n\t\t\t * @param {String} name\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-document-getRoot-root-not-exist: Root with specified name does not exist.',\n\t\t\t\t{ name }\n\t\t\t);\n\t\t}\n\n\t\treturn this.roots.get( name );\n\t}\n\n\t/**\n\t * Checks if root with given name is defined.\n\t *\n\t * @param {String} name Name of root to check.\n\t * @returns {Boolean}\n\t */\n\thasRoot( name ) {\n\t\treturn this.roots.has( name );\n\t}\n\n\t/**\n\t * Returns array with names of all roots (without the {@link #graveyard}) added to the document.\n\t *\n\t * @returns {Array.<String>} Roots names.\n\t */\n\tgetRootNames() {\n\t\treturn Array.from( this.roots.keys() ).filter( name => name != graveyardName );\n\t}\n\n\t/**\n\t * Basing on given `position`, finds and returns a {@link module:engine/model/range~Range Range} instance that is\n\t * nearest to that `position` and is a correct range for selection.\n\t *\n\t * Correct selection range might be collapsed - when it's located in position where text node can be placed.\n\t * Non-collapsed range is returned when selection can be placed around element marked as \"object\" in\n\t * {@link module:engine/model/schema~Schema schema}.\n\t *\n\t * Direction of searching for nearest correct selection range can be specified as:\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 {module:engine/model/position~Position} position Reference position where new selection range should be looked for.\n\t * @param {'both'|'forward'|'backward'} [direction='both'] Search direction.\n\t * @returns {module:engine/model/range~Range|null} Nearest selection range or `null` if one cannot be found.\n\t */\n\tgetNearestSelectionRange( position, direction = 'both' ) {\n\t\t// Return collapsed range if provided position is valid.\n\t\tif ( this.schema.check( { name: '$text', inside: position } ) ) {\n\t\t\treturn new Range( position );\n\t\t}\n\n\t\tlet backwardWalker, forwardWalker;\n\n\t\tif ( direction == 'both' || direction == 'backward' ) {\n\t\t\tbackwardWalker = new TreeWalker( { startPosition: position, direction: 'backward' } );\n\t\t}\n\n\t\tif ( direction == 'both' || direction == 'forward' ) {\n\t\t\tforwardWalker = new TreeWalker( { startPosition: position } );\n\t\t}\n\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\n\t\t\tif ( value.type == type && this.schema.objects.has( value.item.name ) ) {\n\t\t\t\treturn Range.createOn( value.item );\n\t\t\t}\n\n\t\t\tif ( this.schema.check( { name: '$text', inside: value.nextPosition } ) ) {\n\t\t\t\treturn new Range( value.nextPosition );\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Transforms two sets of deltas by themselves. Returns both transformed sets.\n\t *\n\t * @param {Array.<module:engine/model/delta/delta~Delta>} deltasA Array with the first set of deltas to transform. These\n\t * deltas are considered more important (than `deltasB`) when resolving conflicts.\n\t * @param {Array.<module:engine/model/delta/delta~Delta>} deltasB Array with the second set of deltas to transform. These\n\t * deltas are considered less important (than `deltasA`) when resolving conflicts.\n\t * @param {Boolean} [useContext=false] When set to `true`, transformation will store and use additional context\n\t * information to guarantee more expected results. Should be used whenever deltas related to already applied\n\t * deltas are transformed (for example when undoing changes).\n\t * @returns {Object}\n\t * @returns {Array.<module:engine/model/delta/delta~Delta>} return.deltasA The first set of deltas transformed\n\t * by the second set of deltas.\n\t * @returns {Array.<module:engine/model/delta/delta~Delta>} return.deltasB The second set of deltas transformed\n\t * by the first set of deltas.\n\t */\n\ttransformDeltas( deltasA, deltasB, useContext = false ) {\n\t\treturn deltaTransform.transformDeltaSets( deltasA, deltasB, useContext ? this : null );\n\t}\n\n\t/**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @returns {Object} Clone of this object with the document property changed to string.\n\t */\n\ttoJSON() {\n\t\tconst json = clone( this );\n\n\t\t// Due to circular references we need to remove parent reference.\n\t\tjson.selection = '[engine.model.DocumentSelection]';\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Returns default root for this document which is either the first root that was added to the the document using\n\t * {@link #createRoot} or the {@link #graveyard graveyard root} if no other roots were created.\n\t *\n\t * @protected\n\t * @returns {module:engine/model/rootelement~RootElement} The default root for this document.\n\t */\n\t_getDefaultRoot() {\n\t\tfor ( const root of this.roots.values() ) {\n\t\t\tif ( root !== this.graveyard ) {\n\t\t\t\treturn root;\n\t\t\t}\n\t\t}\n\n\t\treturn this.graveyard;\n\t}\n\n\t/**\n\t * Returns a 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's {@link #_getDefaultRoot default root}.\n\t *\n\t * @protected\n\t * @returns {module:engine/model/range~Range}\n\t */\n\t_getDefaultRange() {\n\t\tconst defaultRoot = this._getDefaultRoot();\n\n\t\t// Find the first position where the selection can be put.\n\t\tconst position = new Position( defaultRoot, [ 0 ] );\n\t\tconst nearestRange = this.getNearestSelectionRange( position );\n\n\t\t// If valid selection range is not found - return range collapsed at the beginning of the root.\n\t\treturn nearestRange || new Range( position );\n\t}\n\n\t/**\n\t * Checks whether given {@link module:engine/model/range~Range range} is a valid range for\n\t * {@link #selection document's selection}.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range Range to check.\n\t * @returns {Boolean} `true` if `range` is valid, `false` otherwise.\n\t */\n\t_validateSelectionRange( range ) {\n\t\treturn validateTextNodePosition( range.start ) && validateTextNodePosition( range.end );\n\t}\n\n\t/**\n\t * Fired when document changes by applying an operation.\n\t *\n\t * There are 5 types of change:\n\t *\n\t * * 'insert' when nodes are inserted,\n\t * * 'remove' when nodes are removed,\n\t * * 'reinsert' when remove is undone,\n\t * * 'move' when nodes are moved,\n\t * * 'rename' when element is renamed,\n\t * * 'marker' when a marker changes (added, removed or its range is changed),\n\t * * 'addAttribute' when attributes are added,\n\t * * 'removeAttribute' when attributes are removed,\n\t * * 'changeAttribute' when attributes change,\n\t * * 'addRootAttribute' when attribute for root is added,\n\t * * 'removeRootAttribute' when attribute for root is removed,\n\t * * 'changeRootAttribute' when attribute for root changes.\n\t *\n\t * @event change\n\t * @param {String} type Change type, possible option: 'insert', 'remove', 'reinsert', 'move', 'attribute'.\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/range~Range} [data.range] Range in model containing changed nodes. Note that the range state is\n\t * after changes has been done, i.e. for 'remove' the range will be in the {@link #graveyard graveyard root}.\n\t * The range is not defined for root, rename and marker types.\n\t * @param {module:engine/model/position~Position} [data.sourcePosition] Change source position.\n\t * Exists for 'remove', 'reinsert' and 'move'.\n\t * Note that this position state is before changes has been done, i.e. for 'reinsert' the source position will be in the\n\t * {@link #graveyard graveyard root}.\n\t * @param {String} [data.key] Only for attribute types. Key of changed / inserted / removed attribute.\n\t * @param {*} [data.oldValue] Only for 'removeAttribute', 'removeRootAttribute', 'changeAttribute' or\n\t * 'changeRootAttribute' type.\n\t * @param {*} [data.newValue] Only for 'addAttribute', 'addRootAttribute', 'changeAttribute' or\n\t * 'changeRootAttribute' type.\n\t * @param {module:engine/model/rootelement~RootElement} [data.root] Root element which attributes got changed. This is defined\n\t * only for root types.\n\t * @param {module:engine/model/batch~Batch} batch A {@link module:engine/model/batch~Batch batch}\n\t * of changes which this change is a part of.\n\t */\n\n\t/**\n\t * Fired when all queued document changes are done. See {@link #enqueueChanges}.\n\t *\n\t * @event changesDone\n\t */\n}\n\nmix( Document, EmitterMixin );\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.\nfunction validateTextNodePosition( rangeBoundary ) {\n\tconst textNode = rangeBoundary.textNode;\n\n\tif ( textNode ) {\n\t\tconst data = textNode.data;\n\t\tconst offset = rangeBoundary.offset - textNode.startOffset;\n\n\t\treturn !isInsideSurrogatePair( data, offset ) && !isInsideCombinedSymbol( data, offset );\n\t}\n\n\treturn true;\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 {module:engine/module/treewalker~TreeWalker} [backward] Walker iterating in backward direction.\n// @param {module:engine/module/treewalker~TreeWalker} [forward] Walker iterating in forward direction.\n// @returns {Iterable.<Object>} Object returned at each iteration contains `value` and `walker` (informing which walker returned\n// given value) fields.\nfunction* combineWalkers( backward, forward ) {\n\tlet done = false;\n\n\twhile ( !done ) {\n\t\tdone = true;\n\n\t\tif ( backward ) {\n\t\t\tconst step = backward.next();\n\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\n\t\tif ( forward ) {\n\t\t\tconst step = forward.next();\n\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\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/document.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/editor/editor\n */\n\nimport Config from '@ckeditor/ckeditor5-utils/src/config';\nimport PluginCollection from '../plugincollection';\nimport CommandCollection from '../commandcollection';\nimport Locale from '@ckeditor/ckeditor5-utils/src/locale';\nimport DataController from '@ckeditor/ckeditor5-engine/src/controller/datacontroller';\nimport Document from '@ckeditor/ckeditor5-engine/src/model/document';\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Class representing a basic editor. It contains a base architecture, without much additional logic.\n *\n * See also {@link module:core/editor/standardeditor~StandardEditor}.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Editor {\n\t/**\n\t * Creates a new instance of the Editor class.\n\t *\n\t * @param {Object} config The editor config.\n\t */\n\tconstructor( config ) {\n\t\tconst availablePlugins = this.constructor.build && this.constructor.build.plugins;\n\n\t\t/**\n\t\t * Holds all configurations specific to this editor instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/config~Config}\n\t\t */\n\t\tthis.config = new Config( config, this.constructor.build && this.constructor.build.config );\n\n\t\tthis.config.define( 'plugins', availablePlugins );\n\n\t\t/**\n\t\t * The plugins loaded and in use by this editor instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/plugincollection~PluginCollection}\n\t\t */\n\t\tthis.plugins = new PluginCollection( this, availablePlugins );\n\n\t\t/**\n\t\t * Commands registered to the editor.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/commandcollection~CommandCollection}\n\t\t */\n\t\tthis.commands = new CommandCollection();\n\n\t\t/**\n\t\t * @readonly\n\t\t * @member {module:utils/locale~Locale}\n\t\t */\n\t\tthis.locale = new Locale( this.config.get( 'lang' ) );\n\n\t\t/**\n\t\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t\t *\n\t\t * @see module:utils/locale~Locale#t\n\t\t * @method #t\n\t\t */\n\t\tthis.t = this.locale.t;\n\n\t\t/**\n\t\t * The editor's model document.\n\t\t *\n\t\t * The center of the editor's abstract data model. The document contains\n\t\t * {@link module:engine/model/document~Document#getRoot all editing roots},\n\t\t * {@link module:engine/model/document~Document#selection} and allows\n\t\t * applying changes to through the {@link module:engine/model/document~Document#batch batch interface}.\n\t\t *\n\t\t * Besides the model document, the editor usually contains two controllers \n\t\t * {@link #data data controller} and {@link #editing editing controller}.\n\t\t * The former is used e.g. when setting or retrieving editor data and contains a useful\n\t\t * set of methods for operating on the content. The latter controls user input and rendering\n\t\t * the content for editing.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/document~Document}\n\t\t */\n\t\tthis.document = new Document();\n\n\t\t/**\n\t\t * The {@link module:engine/controller/datacontroller~DataController data controller}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/controller/datacontroller~DataController}\n\t\t */\n\t\tthis.data = new DataController( this.document );\n\n\t\t/**\n\t\t * Defines whether this editor is in read-only mode.\n\t\t *\n\t\t * In read-only mode the editor {@link #commands commands} are disabled so it is not possible\n\t\t * to modify document using them.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * The {@link module:engine/controller/editingcontroller~EditingController editing controller}.\n\t\t *\n\t\t * This property is set by more specialized editor classes (such as {@link module:core/editor/standardeditor~StandardEditor}),\n\t\t * however, it's required for features to work as their engine-related parts will try to connect converters.\n\t\t *\n\t\t * When defining a virtual editor class, like one working in Node.js, it's possible to plug a virtual\n\t\t * editing controller which only instantiates necessary properties, but without any observers and listeners.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/controller/editingcontroller~EditingController} #editing\n\t\t */\n\t}\n\n\t/**\n\t * Loads and initializes plugins specified in the config.\n\t *\n\t * @returns {Promise} A promise which resolves once the initialization is completed.\n\t */\n\tinitPlugins() {\n\t\tconst that = this;\n\t\tconst config = this.config;\n\n\t\treturn loadPlugins()\n\t\t\t.then( loadedPlugins => {\n\t\t\t\treturn initPlugins( loadedPlugins, 'init' )\n\t\t\t\t\t.then( () => initPlugins( loadedPlugins, 'afterInit' ) );\n\t\t\t} )\n\t\t\t.then( () => this.fire( 'pluginsReady' ) );\n\n\t\tfunction loadPlugins() {\n\t\t\tconst plugins = config.get( 'plugins' ) || [];\n\t\t\tconst removePlugins = config.get( 'removePlugins' ) || [];\n\n\t\t\treturn that.plugins.load( plugins, removePlugins );\n\t\t}\n\n\t\tfunction initPlugins( loadedPlugins, method ) {\n\t\t\treturn loadedPlugins.reduce( ( promise, plugin ) => {\n\t\t\t\tif ( !plugin[ method ] ) {\n\t\t\t\t\treturn promise;\n\t\t\t\t}\n\n\t\t\t\treturn promise.then( plugin[ method ].bind( plugin ) );\n\t\t\t}, Promise.resolve() );\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * @fires destroy\n\t * @returns {Promise} A promise that resolves once the editor instance is fully destroyed.\n\t */\n\tdestroy() {\n\t\tthis.fire( 'destroy' );\n\n\t\tthis.stopListening();\n\n\t\tthis.commands.destroy();\n\n\t\treturn this.plugins.destroy()\n\t\t\t.then( () => {\n\t\t\t\tthis.document.destroy();\n\t\t\t\tthis.data.destroy();\n\t\t\t} );\n\t}\n\n\t/**\n\t * Executes specified command with given parameters.\n\t *\n\t * Shorthand for:\n\t *\n\t *\t\teditor.commands.get( commandName ).execute( ... );\n\t *\n\t * @param {String} commandName Name of command to execute.\n\t * @param {*} [...commandParams] Command parameters.\n\t */\n\texecute( ...args ) {\n\t\tthis.commands.execute( ...args );\n\t}\n\n\t/**\n\t * Creates a basic editor instance.\n\t *\n\t * @param {Object} config The editor config. You can find the list of config options in\n\t * {@link module:core/editor/editorconfig~EditorConfig}.\n\t * @returns {Promise} Promise resolved once editor is ready.\n\t * @returns {module:core/editor/editor~Editor} return.editor The editor instance.\n\t */\n\tstatic create( config ) {\n\t\treturn new Promise( resolve => {\n\t\t\tconst editor = new this( config );\n\n\t\t\tresolve(\n\t\t\t\teditor.initPlugins()\n\t\t\t\t\t.then( () => {\n\t\t\t\t\t\teditor.fire( 'dataReady' );\n\t\t\t\t\t\teditor.fire( 'ready' );\n\t\t\t\t\t} )\n\t\t\t\t\t.then( () => editor )\n\t\t\t);\n\t\t} );\n\t}\n}\n\nmix( Editor, ObservableMixin );\n\n/**\n * Fired after {@link #initPlugins plugins are initialized}.\n *\n * @event pluginsReady\n */\n\n/**\n * Fired when the editor UI is ready. This event won't be fired if the editor has no UI.\n *\n * @event uiReady\n */\n\n/**\n * Fired when the data loaded to the editor is ready. If a specific editor doesn't load\n * any data initially, this event will be fired right before {@link #event:ready}.\n *\n * @event dataReady\n */\n\n/**\n * Fired when {@link #event:pluginsReady plugins}, {@link #event:uiReady UI} and {@link #event:dataReady data} and all additional\n * editor components are ready.\n *\n * @event ready\n */\n\n/**\n * Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to\n * perform the clean-up in any plugin.\n *\n * @event destroy\n */\n\n/**\n * Additional data built into the editor class. It's used while bundling the editor in order to provide\n * the default set of plugins and config options which are later used during editor initialization.\n *\n * Two properties are supported:\n *\n * * `plugins` an array of plugin constructors. They will be automatically initialized by the editor, unless listed\n * in `config.removePlugins` or unless `config.plugins` is passed.\n * * `config` the defalt config options.\n *\n * @static\n * @member {Object} module:core/editor/editor~Editor.build\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/src/editor/editor.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/isdomnode\n */\n\nimport isNative from '../lib/lodash/isNative';\n\n/**\n * Checks if the object is a native DOM Node.\n *\n * @param {*} obj\n * @returns {Boolean}\n */\nexport default function isDomNode( obj ) {\n\treturn !!( obj && isNative( obj.addEventListener ) );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/isdomnode.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/emittermixin\n */\n\nimport { default as EmitterMixin, _getEmitterListenedTo, _setEmitterId } from '../emittermixin';\nimport uid from '../uid';\nimport extend from '../lib/lodash/extend';\nimport isDomNode from './isdomnode';\n\n/**\n * Mixin that injects the DOM events API into its host. It provides the API\n * compatible with {@link module:utils/emittermixin~EmitterMixin}.\n *\n * DOM emitter mixin is by default available in the {@link module:ui/view~View} class,\n * but it can also be mixed into any other class:\n *\n *\t\timport mix from '../utils/mix.js';\n *\t\timport DomEmitterMixin from '../utils/dom/emittermixin.js';\n *\n *\t\tclass SomeView {}\n *\t\tmix( SomeView, DomEmitterMixin );\n *\n *\t\tconst view = new SomeView();\n *\t\tview.listenTo( domElement, ( evt, domEvt ) => {\n *\t\t\tconsole.log( evt, domEvt );\n *\t\t} );\n *\n * @mixin module:utils/dom/emittermixin~EmitterMixin\n * @mixes module:utils/emittermixin~EmitterMixin\n * @implements module:utils/dom/emittermixin~Emitter\n */\nconst DomEmitterMixin = extend( {}, EmitterMixin, {\n\t/**\n\t * Registers a callback function to be executed when an event is fired in a specific Emitter or DOM Node.\n\t * It is backwards compatible with {@link module:utils/emittermixin~EmitterMixin#listenTo}.\n\t *\n\t * @param {module:utils/emittermixin~Emitter|Node} emitter The object that fires the event.\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to be called on event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n\t * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n\t * order they were added.\n\t * @param {Boolean} [options.useCapture=false] Indicates that events of this type will be dispatched to the registered\n\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t *\n\t * @method module:utils/dom/emittermixin~EmitterMixin#listenTo\n\t */\n\tlistenTo( ...args ) {\n\t\tconst emitter = args[ 0 ];\n\n\t\t// Check if emitter is an instance of DOM Node. If so, replace the argument with\n\t\t// corresponding ProxyEmitter (or create one if not existing).\n\t\tif ( isDomNode( emitter ) ) {\n\t\t\targs[ 0 ] = this._getProxyEmitter( emitter ) || new ProxyEmitter( emitter );\n\t\t}\n\n\t\t// Execute parent class method with Emitter (or ProxyEmitter) instance.\n\t\tEmitterMixin.listenTo.apply( this, args );\n\t},\n\n\t/**\n\t * Stops listening for events. It can be used at different levels:\n\t * It is backwards compatible with {@link module:utils/emittermixin~EmitterMixin#listenTo}.\n\t *\n\t * * To stop listening to a specific callback.\n\t * * To stop listening to a specific event.\n\t * * To stop listening to all events fired by a specific object.\n\t * * To stop listening to all events fired by all object.\n\t *\n\t * @param {module:utils/emittermixin~Emitter|Node} [emitter] The object to stop listening to. If omitted, stops it for all objects.\n\t * @param {String} [event] (Requires the `emitter`) The name of the event to stop listening to. If omitted, stops it\n\t * for all events from `emitter`.\n\t * @param {Function} [callback] (Requires the `event`) The function to be removed from the call list for the given\n\t * `event`.\n\t *\n\t * @method module:utils/dom/emittermixin~EmitterMixin#stopListening\n\t */\n\tstopListening( ...args ) {\n\t\tconst emitter = args[ 0 ];\n\n\t\t// Check if emitter is an instance of DOM Node. If so, replace the argument with corresponding ProxyEmitter.\n\t\tif ( isDomNode( emitter ) ) {\n\t\t\tconst proxy = this._getProxyEmitter( emitter );\n\n\t\t\t// Element has no listeners.\n\t\t\tif ( !proxy ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\targs[ 0 ] = proxy;\n\t\t}\n\n\t\t// Execute parent class method with Emitter (or ProxyEmitter) instance.\n\t\tEmitterMixin.stopListening.apply( this, args );\n\t},\n\n\t/**\n\t * Retrieves ProxyEmitter instance for given DOM Node residing in this Host.\n\t *\n\t * @param {Node} node DOM Node of the ProxyEmitter.\n\t * @method module:utils/dom/emittermixin~EmitterMixin#_getProxyEmitter\n\t * @return {module:utils/dom/emittermixin~ProxyEmitter} ProxyEmitter instance or null.\n\t */\n\t_getProxyEmitter( node ) {\n\t\treturn _getEmitterListenedTo( this, getNodeUID( node ) );\n\t}\n} );\n\nexport default DomEmitterMixin;\n\n/**\n * Creates a ProxyEmitter instance. Such an instance is a bridge between a DOM Node firing events\n * and any Host listening to them. It is backwards compatible with {@link module:utils/emittermixin~EmitterMixin#on}.\n *\n * listenTo( click, ... )\n * +-----------------------------------------+\n * | stopListening( ... ) |\n * +----------------------------+ | addEventListener( click, ... )\n * | Host | | +---------------------------------------------+\n * +----------------------------+ | | removeEventListener( click, ... ) |\n * | _listeningTo: { | +----------v-------------+ |\n * | UID: { | | ProxyEmitter | |\n * | emitter: ProxyEmitter, | +------------------------+ +------------v----------+\n * | callbacks: { | | events: { | | Node (HTMLElement) |\n * | click: [ callbacks ] | | click: [ callbacks ] | +-----------------------+\n * | } | | }, | | data-ck-expando: UID |\n * | } | | _domNode: Node, | +-----------------------+\n * | } | | _domListeners: {}, | |\n * | +------------------------+ | | _emitterId: UID | |\n * | | DomEmitterMixin | | +--------------^---------+ |\n * | +------------------------+ | | | |\n * +--------------^-------------+ | +---------------------------------------------+\n * | | click (DOM Event)\n * +-----------------------------------------+\n * fire( click, DOM Event )\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n * @implements module:utils/dom/emittermixin~Emitter\n * @private\n */\nclass ProxyEmitter {\n\t/**\n\t * @param {Node} node DOM Node that fires events.\n\t * @returns {Object} ProxyEmitter instance bound to the DOM Node.\n\t */\n\tconstructor( node ) {\n\t\t// Set emitter ID to match DOM Node \"expando\" property.\n\t\t_setEmitterId( this, getNodeUID( node ) );\n\n\t\t// Remember the DOM Node this ProxyEmitter is bound to.\n\t\tthis._domNode = node;\n\t}\n}\n\nextend( ProxyEmitter.prototype, EmitterMixin, {\n\t/**\n\t * Collection of native DOM listeners.\n\t *\n\t * @private\n\t * @member {Object} module:utils/dom/emittermixin~ProxyEmitter#_domListeners\n\t */\n\n\t/**\n\t * Registers a callback function to be executed when an event is fired.\n\t *\n\t * It attaches a native DOM listener to the DOM Node. When fired,\n\t * a corresponding Emitter event will also fire with DOM Event object as an argument.\n\t *\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to be called on event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n\t * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n\t * order they were added.\n\t * @param {Boolean} [options.useCapture=false] Indicates that events of this type will be dispatched to the registered\n\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t *\n\t * @method module:utils/dom/emittermixin~ProxyEmitter#on\n\t */\n\ton( event, callback, options = {} ) {\n\t\t// Execute parent class method first.\n\t\tEmitterMixin.on.call( this, event, callback, options );\n\n\t\t// If the DOM Listener for given event already exist it is pointless\n\t\t// to attach another one.\n\t\tif ( this._domListeners && this._domListeners[ event ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domListener = this._createDomListener( event, !!options.useCapture );\n\n\t\t// Attach the native DOM listener to DOM Node.\n\t\tthis._domNode.addEventListener( event, domListener, !!options.useCapture );\n\n\t\tif ( !this._domListeners ) {\n\t\t\tthis._domListeners = {};\n\t\t}\n\n\t\t// Store the native DOM listener in this ProxyEmitter. It will be helpful\n\t\t// when stopping listening to the event.\n\t\tthis._domListeners[ event ] = domListener;\n\t},\n\n\t/**\n\t * Stops executing the callback on the given event.\n\t *\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to stop being called.\n\t *\n\t * @method module:utils/dom/emittermixin~ProxyEmitter#off\n\t */\n\toff( event, callback ) {\n\t\t// Execute parent class method first.\n\t\tEmitterMixin.off.call( this, event, callback );\n\n\t\tlet events;\n\n\t\t// Remove native DOM listeners which are orphans. If no callbacks\n\t\t// are awaiting given event, detach native DOM listener from DOM Node.\n\t\t// See: {@link on}.\n\n\t\tif ( this._domListeners[ event ] && ( !( events = this._events[ event ] ) || !events.callbacks.length ) ) {\n\t\t\tthis._domListeners[ event ].removeListener();\n\t\t}\n\t},\n\n\t/**\n\t * Create a native DOM listener callback. When the native DOM event\n\t * is fired it will fire corresponding event on this ProxyEmitter.\n\t * Note: A native DOM Event is passed as an argument.\n\t *\n\t * @private\n\t * @param {String} event\n\t *\n\t * @method module:utils/dom/emittermixin~ProxyEmitter#_createDomListener\n\t * @param {String} event The name of the event.\n\t * @param {Boolean} useCapture Indicates whether the listener was created for capturing event.\n\t * @returns {Function} The DOM listener callback.\n\t */\n\t_createDomListener( event, useCapture ) {\n\t\tconst domListener = domEvt => {\n\t\t\tthis.fire( event, domEvt );\n\t\t};\n\n\t\t// Supply the DOM listener callback with a function that will help\n\t\t// detach it from the DOM Node, when it is no longer necessary.\n\t\t// See: {@link off}.\n\t\tdomListener.removeListener = () => {\n\t\t\tthis._domNode.removeEventListener( event, domListener, useCapture );\n\t\t\tdelete this._domListeners[ event ];\n\t\t};\n\n\t\treturn domListener;\n\t}\n} );\n\n// Gets an unique DOM Node identifier. The identifier will be set if not defined.\n//\n// @private\n// @param {Node} node\n// @return {String} UID for given DOM Node.\nfunction getNodeUID( node ) {\n\treturn node[ 'data-ck-expando' ] || ( node[ 'data-ck-expando' ] = uid() );\n}\n\n/**\n * Interface representing classes which mix in {@link module:utils/dom/emittermixin~EmitterMixin}.\n *\n * @interface Emitter\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/emittermixin.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/keystrokehandler\n */\n\nimport DomEmitterMixin from './dom/emittermixin';\nimport { getCode, parseKeystroke } from './keyboard';\n\n/**\n * Keystroke handler registers keystrokes so the callbacks associated\n * with these keystrokes will be executed if the matching `keydown` is fired\n * by a defined emitter.\n *\n *\t\tconst handler = new KeystrokeHandler();\n *\n *\t\thandler.listenTo( emitter );\n *\n *\t\thandler.set( 'Ctrl+A', ( keyEvtData, cancel ) => {\n *\t\t\tconsole.log( 'Ctrl+A has been pressed' );\n *\t\t\tcancel();\n *\t\t} );\n */\nexport default class KeystrokeHandler {\n\t/**\n\t * Creates an instance of the keystroke handler.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Listener used to listen to events for easier keystroke handler destruction.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:utils/dom/emittermixin~Emitter}\n\t\t */\n\t\tthis._listener = Object.create( DomEmitterMixin );\n\t}\n\n\t/**\n\t * Starts listening for `keydown` events from a given emitter.\n\t *\n\t * @param {module:utils/emittermixin~Emitter} emitter\n\t */\n\tlistenTo( emitter ) {\n\t\t// The #_listener works here as a kind of dispatcher. It groups the events coming from the same\n\t\t// keystroke so the listeners can be attached to them with different priorities.\n\t\t//\n\t\t// E.g. all the keystrokes with the `keyCode` of 42 coming from the `emitter` are propagated\n\t\t// as a `_keydown:42` event by the `_listener`. If there's a callback created by the `set`\n\t\t// method for this 42 keystroke, it listens to the `_listener#_keydown:42` event only and interacts\n\t\t// only with other listeners of this particular event, thus making it possible to prioritize\n\t\t// the listeners and safely cancel execution, when needed. Instead of duplicating the Emitter logic,\n\t\t// the KeystrokeHandler reuses it to do its job.\n\t\tthis._listener.listenTo( emitter, 'keydown', ( evt, keyEvtData ) => {\n\t\t\tthis._listener.fire( '_keydown:' + getCode( keyEvtData ), keyEvtData );\n\t\t} );\n\t}\n\n\t/**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * @param {String|Array.<String|Number>} keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param {Function} callback A function called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a helper to both `preventDefault` and `stopPropagation` of the event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of the keystroke\n\t * callback. The higher the priority value the sooner the callback will be executed. Keystrokes having the same priority\n\t * are called in the order they were added.\n\t */\n\tset( keystroke, callback, options = {} ) {\n\t\tconst keyCode = parseKeystroke( keystroke );\n\t\tconst priority = options.priority;\n\n\t\t// Execute the passed callback on KeystrokeHandler#_keydown.\n\t\t// TODO: https://github.com/ckeditor/ckeditor5-utils/issues/144\n\t\tthis._listener.listenTo( this._listener, '_keydown:' + keyCode, ( evt, keyEvtData ) => {\n\t\t\tcallback( keyEvtData, () => {\n\t\t\t\t// Stop the event in the DOM: no listener in the web page\n\t\t\t\t// will be triggered by this event.\n\t\t\t\tkeyEvtData.preventDefault();\n\t\t\t\tkeyEvtData.stopPropagation();\n\n\t\t\t\t// Stop the event in the KeystrokeHandler: no more callbacks\n\t\t\t\t// will be executed for this keystroke.\n\t\t\t\tevt.stop();\n\t\t\t} );\n\n\t\t\t// Mark this keystroke as handled by the callback. See: #press.\n\t\t\tevt.return = true;\n\t\t}, { priority } );\n\t}\n\n\t/**\n\t * Triggers a keystroke handler for a specified key combination, if such a keystroke was {@link #set defined}.\n\t *\n\t * @param {module:engine/view/observer/keyobserver~KeyEventData} keyEvtData Key event data.\n\t * @returns {Boolean} Whether the keystroke was handled.\n\t */\n\tpress( keyEvtData ) {\n\t\treturn !!this._listener.fire( '_keydown:' + getCode( keyEvtData ), keyEvtData );\n\t}\n\n\t/**\n\t * Destroys the keystroke handler.\n\t */\n\tdestroy() {\n\t\tthis._listener.stopListening();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/keystrokehandler.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/count\n */\n\n/**\n * Returns the number of items return by the iterator.\n *\n *\t\tcount( [ 1, 2, 3, 4, 5 ] ); // 5;\n *\n * @param {Iterable.<*>} iterator Any iterator.\n * @returns {Number} Number of items returned by that iterator.\n */\nexport default function count( iterator ) {\n\tlet count = 0;\n\n\tfor ( const _ of iterator ) { // eslint-disable-line no-unused-vars\n\t\tcount++;\n\t}\n\n\treturn count;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/count.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/selection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Range from './range';\nimport Position from './position';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport Element from './element';\nimport count from '@ckeditor/ckeditor5-utils/src/count';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * Class representing selection in tree view.\n *\n * Selection can consist of {@link module:engine/view/range~Range ranges} that can be added using\n * {@link module:engine/view/selection~Selection#addRange addRange}\n * and {@link module:engine/view/selection~Selection#setRanges setRanges} methods.\n * Both methods create copies of provided ranges and store those copies internally. Further modifications to passed\n * ranges will not change selection's state.\n * Selection's ranges can be obtained via {@link module:engine/view/selection~Selection#getRanges getRanges},\n * {@link module:engine/view/selection~Selection#getFirstRange getFirstRange}\n * and {@link module:engine/view/selection~Selection#getLastRange getLastRange}\n * methods, which return copies of ranges stored inside selection. Modifications made on these copies will not change\n * selection's state. Similar situation occurs when getting {@link module:engine/view/selection~Selection#anchor anchor},\n * {@link module:engine/view/selection~Selection#focus focus}, {@link module:engine/view/selection~Selection#getFirstPosition first} and\n * {@link module:engine/view/selection~Selection#getLastPosition last} positions - all will return copies of requested positions.\n */\nexport default class Selection {\n\t/**\n\t * Creates new selection instance.\n\t *\n\t * @param {Iterable.<module:engine/view/range~Range>} [ranges] An optional array of ranges to set.\n\t * @param {Boolean} [isLastBackward] An optional 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\tconstructor( ranges, isLastBackward ) {\n\t\t/**\n\t\t * Stores all ranges that are selected.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/view/range~Range>}\n\t\t */\n\t\tthis._ranges = [];\n\n\t\t/**\n\t\t * Specifies whether the last added range was added as a backward or forward range.\n\t\t *\n\t\t * @protected\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._lastRangeBackward = false;\n\n\t\t/**\n\t\t * Specifies whether selection instance is fake.\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._isFake = false;\n\n\t\t/**\n\t\t * Fake selection's label.\n\t\t *\n\t\t * @private\n\t\t * @member {String}\n\t\t */\n\t\tthis._fakeSelectionLabel = '';\n\n\t\tif ( ranges ) {\n\t\t\tthis.setRanges( ranges, isLastBackward );\n\t\t}\n\t}\n\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 * @fires change\n\t * @param {Boolean} [value=true] If set to true selection will be marked as `fake`.\n\t * @param {Object} [options] Additional options.\n\t * @param {String} [options.label=''] Fake selection label.\n\t */\n\tsetFake( value = true, options = {} ) {\n\t\tthis._isFake = value;\n\t\tthis._fakeSelectionLabel = value ? options.label || '' : '';\n\n\t\tthis.fire( 'change' );\n\t}\n\n\t/**\n\t * Returns true if selection instance is marked as `fake`.\n\t *\n\t * @see #setFake\n\t * @returns {Boolean}\n\t */\n\tget isFake() {\n\t\treturn this._isFake;\n\t}\n\n\t/**\n\t * Returns fake selection label.\n\t *\n\t * @see #setFake\n\t * @returns {String}\n\t */\n\tget fakeSelectionLabel() {\n\t\treturn this._fakeSelectionLabel;\n\t}\n\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 * @type {module:engine/view/position~Position}\n\t */\n\tget anchor() {\n\t\tif ( !this._ranges.length ) {\n\t\t\treturn null;\n\t\t}\n\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\t\tconst anchor = this._lastRangeBackward ? range.end : range.start;\n\n\t\treturn Position.createFromPosition( anchor );\n\t}\n\n\t/**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * @see #anchor\n\t * @type {module:engine/view/position~Position}\n\t */\n\tget focus() {\n\t\tif ( !this._ranges.length ) {\n\t\t\treturn null;\n\t\t}\n\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\t\tconst focus = this._lastRangeBackward ? range.start : range.end;\n\n\t\treturn Position.createFromPosition( focus );\n\t}\n\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\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this.rangeCount === 1 && this._ranges[ 0 ].isCollapsed;\n\t}\n\n\t/**\n\t * Returns number of ranges in selection.\n\t *\n\t * @type {Number}\n */\n\tget rangeCount() {\n\t\treturn this._ranges.length;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isBackward() {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`\n\t * if the selection is not inside an editable element.\n\t *\n\t * @type {module:engine/view/editableelement~EditableElement|null}\n\t */\n\tget editableElement() {\n\t\tif ( this.anchor ) {\n\t\t\treturn this.anchor.editableElement;\n\t\t}\n\n\t\treturn null;\n\t}\n\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~Range#start start} to {@link module:engine/view/range~Range#end end}\n\t * or from {@link module:engine/view/range~Range#end end} to {@link module:engine/view/range~Range#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 * @fires change\n\t * @param {module:engine/view/range~Range} range\n\t * @param {Boolean} isBackward\n\t */\n\taddRange( range, isBackward ) {\n\t\tif ( !( range instanceof Range ) ) {\n\t\t\tthrow new CKEditorError( 'view-selection-invalid-range: Invalid Range.' );\n\t\t}\n\n\t\tthis._pushRange( range );\n\t\tthis._lastRangeBackward = !!isBackward;\n\t\tthis.fire( 'change' );\n\t}\n\n\t/**\n\t * Returns an iterator that contains copies of all ranges added to the selection.\n\t *\n\t * @returns {Iterator.<module:engine/view/range~Range>}\n\t */\n\t* getRanges() {\n\t\tfor ( const range of this._ranges ) {\n\t\t\tyield Range.createFromRange( range );\n\t\t}\n\t}\n\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~Range#start start} position {@link module:engine/view/position~Position#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\t * @returns {module:engine/view/range~Range|null}\n\t */\n\tgetFirstRange() {\n\t\tlet first = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !first || range.start.isBefore( first.start ) ) {\n\t\t\t\tfirst = range;\n\t\t\t}\n\t\t}\n\n\t\treturn first ? Range.createFromRange( first ) : null;\n\t}\n\n\t/**\n\t * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}\n\t * position {@link module:engine/view/position~Position#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\t * @returns {module:engine/view/range~Range|null}\n\t */\n\tgetLastRange() {\n\t\tlet last = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !last || range.end.isAfter( last.end ) ) {\n\t\t\t\tlast = range;\n\t\t\t}\n\t\t}\n\n\t\treturn last ? Range.createFromRange( last ) : null;\n\t}\n\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~Position#isBefore is before} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/position~Position|null}\n\t */\n\tgetFirstPosition() {\n\t\tconst firstRange = this.getFirstRange();\n\n\t\treturn firstRange ? Position.createFromPosition( firstRange.start ) : null;\n\t}\n\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~Position#isAfter is after} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/position~Position|null}\n\t */\n\tgetLastPosition() {\n\t\tconst lastRange = this.getLastRange();\n\n\t\treturn lastRange ? Position.createFromPosition( lastRange.end ) : null;\n\t}\n\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 {module:engine/view/selection~Selection} otherSelection Selection to compare with.\n\t * @returns {Boolean} `true` if selections are equal, `false` otherwise.\n\t */\n\tisEqual( otherSelection ) {\n\t\tif ( this.isFake != otherSelection.isFake ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.isFake && this.fakeSelectionLabel != otherSelection.fakeSelectionLabel ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.rangeCount != otherSelection.rangeCount ) {\n\t\t\treturn false;\n\t\t} else if ( this.rangeCount === 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !this.anchor.isEqual( otherSelection.anchor ) || !this.focus.isEqual( otherSelection.focus ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const thisRange of this._ranges ) {\n\t\t\tlet found = false;\n\n\t\t\tfor ( const otherRange of otherSelection._ranges ) {\n\t\t\t\tif ( thisRange.isEqual( otherRange ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\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~Range#getTrimmed trimmed} ranges from one selection are\n\t * equal to any trimmed range from other selection.\n\t *\n\t * @param {module:engine/view/selection~Selection} otherSelection Selection to compare with.\n\t * @returns {Boolean} `true` if selections are similar, `false` otherwise.\n\t */\n\tisSimilar( otherSelection ) {\n\t\tif ( this.isBackward != otherSelection.isBackward ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst numOfRangesA = count( this.getRanges() );\n\t\tconst numOfRangesB = count( otherSelection.getRanges() );\n\n\t\t// If selections have different number of ranges, they cannot be similar.\n\t\tif ( numOfRangesA != numOfRangesB ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If both selections have no ranges, they are similar.\n\t\tif ( numOfRangesA == 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if each range in one selection has a similar range in other selection.\n\t\tfor ( let rangeA of this.getRanges() ) {\n\t\t\trangeA = rangeA.getTrimmed();\n\n\t\t\tlet found = false;\n\n\t\t\tfor ( let rangeB of otherSelection.getRanges() ) {\n\t\t\t\trangeB = rangeB.getTrimmed();\n\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\n\t\t\t// For `rangeA`, neither range in `otherSelection` was similar. So selections are not similar.\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// There were no ranges that weren't matched. Selections are similar.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Removes all ranges that were added to the selection.\n\t *\n\t * @fires change\n\t */\n\tremoveAllRanges() {\n\t\tif ( this._ranges.length ) {\n\t\t\tthis._ranges = [];\n\t\t\tthis.fire( 'change' );\n\t\t}\n\t}\n\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 (see {@link #addRange addRange}).\n\t *\n\t * @fires change\n\t * @param {Iterable.<module:engine/view/range~Range>} newRanges Iterable object of ranges to set.\n\t * @param {Boolean} [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\tsetRanges( newRanges, isLastBackward ) {\n\t\tthis._ranges = [];\n\n\t\tfor ( const range of newRanges ) {\n\t\t\tif ( !( range instanceof Range ) ) {\n\t\t\t\tthrow new CKEditorError( 'view-selection-invalid-range: Invalid Range.' );\n\t\t\t}\n\n\t\t\tthis._pushRange( range );\n\t\t}\n\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\t\tthis.fire( 'change' );\n\t}\n\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~Selection selection}, {@link module:engine/view/position~Position position},\n\t * {@link module:engine/view/range~Range range} or an iterable of {@link module:engine/view/range~Range ranges}.\n\t *\n\t * @param {module:engine/view/selection~Selection|module:engine/view/position~Position|\n\t * Iterable.<module:engine/view/range~Range>|module:engine/view/range~Range} selectable\n\t */\n\tsetTo( selectable ) {\n\t\tif ( selectable instanceof Selection ) {\n\t\t\tthis._isFake = selectable._isFake;\n\t\t\tthis._fakeSelectionLabel = selectable._fakeSelectionLabel;\n\t\t\tthis.setRanges( selectable.getRanges(), selectable.isBackward );\n\t\t} else if ( selectable instanceof Range ) {\n\t\t\tthis.setRanges( [ selectable ] );\n\t\t} else if ( isIterable( selectable ) ) {\n\t\t\t// We assume that the selectable is an iterable of ranges.\n\t\t\tthis.setRanges( selectable );\n\t\t} else {\n\t\t\t// We assume that the selectable is a position.\n\t\t\tthis.setRanges( [ new Range( selectable ) ] );\n\t\t}\n\t}\n\n\t/**\n\t * Sets this selection in the provided element.\n\t *\n\t * @param {module:engine/view/element~Element} element\n\t */\n\tsetIn( element ) {\n\t\tthis.setRanges( [ Range.createIn( element ) ] );\n\t}\n\n\t/**\n\t * Sets this selection on the provided item.\n\t *\n\t * @param {module:engine/view/item~Item} item\n\t */\n\tsetOn( item ) {\n\t\tthis.setRanges( [ Range.createOn( item ) ] );\n\t}\n\n\t/**\n\t * Sets collapsed selection at the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/position~Position.createAt} parameters.\n\t *\n\t * @fires change\n\t * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tsetCollapsedAt( itemOrPosition, offset ) {\n\t\tconst pos = Position.createAt( itemOrPosition, offset );\n\t\tconst range = new Range( pos, pos );\n\n\t\tthis.setRanges( [ range ] );\n\t}\n\n\t/**\n\t * Collapses selection to the selection's {@link #getFirstPosition first position}.\n\t * All ranges, besides the collapsed one, will be removed. Nothing will change if there are no ranges stored\n\t * inside selection.\n\t *\n\t * @fires change\n\t */\n\tcollapseToStart() {\n\t\tconst startPosition = this.getFirstPosition();\n\n\t\tif ( startPosition !== null ) {\n\t\t\tthis.setRanges( [ new Range( startPosition, startPosition ) ] );\n\t\t}\n\t}\n\n\t/**\n\t * Collapses selection to the selection's {@link #getLastPosition last position}.\n\t * All ranges, besides the collapsed one, will be removed. Nothing will change if there are no ranges stored\n\t * inside selection.\n\t *\n\t * @fires change\n\t */\n\tcollapseToEnd() {\n\t\tconst endPosition = this.getLastPosition();\n\n\t\tif ( endPosition !== null ) {\n\t\t\tthis.setRanges( [ new Range( endPosition, endPosition ) ] );\n\t\t}\n\t}\n\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 {@link module:engine/view/position~Position.createAt} parameters.\n\t *\n\t * @fires change\n\t * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tmoveFocusTo( itemOrPosition, offset ) {\n\t\tif ( this.anchor === null ) {\n\t\t\t/**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error view-selection-moveFocusTo-no-ranges\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-selection-moveFocusTo-no-ranges: Cannot set selection focus if there are no ranges in selection.'\n\t\t\t);\n\t\t}\n\n\t\tconst newFocus = Position.createAt( itemOrPosition, offset );\n\n\t\tif ( newFocus.compareWith( this.focus ) == 'same' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst anchor = this.anchor;\n\n\t\tthis._ranges.pop();\n\n\t\tif ( newFocus.compareWith( anchor ) == 'before' ) {\n\t\t\tthis.addRange( new Range( newFocus, anchor ), true );\n\t\t} else {\n\t\t\tthis.addRange( new Range( anchor, newFocus ) );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/view/element~Element 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\t * @returns {module:engine/view/element~Element|null}\n\t */\n\tgetSelectedElement() {\n\t\tif ( this.rangeCount !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst range = this.getFirstRange();\n\t\tconst nodeAfterStart = range.start.nodeAfter;\n\t\tconst nodeBeforeEnd = range.end.nodeBefore;\n\n\t\treturn ( nodeAfterStart instanceof Element && nodeAfterStart == nodeBeforeEnd ) ? nodeAfterStart : null;\n\t}\n\n\t/**\n\t * Creates and returns an instance of `Selection` that is a clone of given selection, meaning that it has same\n\t * ranges and same direction as this selection.\n\t *\n\t * @params {module:engine/view/selection~Selection} otherSelection Selection to be cloned.\n\t * @returns {module:engine/view/selection~Selection} `Selection` instance that is a clone of given selection.\n\t */\n\tstatic createFromSelection( otherSelection ) {\n\t\tconst selection = new Selection();\n\t\tselection.setTo( otherSelection );\n\n\t\treturn selection;\n\t}\n\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 * @private\n\t * @param {module:engine/view/range~Range} range\n\t */\n\t_pushRange( range ) {\n\t\tfor ( const storedRange of this._ranges ) {\n\t\t\tif ( range.isIntersecting( storedRange ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to add a range that intersects with another range from selection.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-range-intersects\n\t\t\t\t * @param {module:engine/view/range~Range} addedRange Range that was added to the selection.\n\t\t\t\t * @param {module:engine/view/range~Range} intersectingRange Range from selection that intersects with `addedRange`.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'view-selection-range-intersects: Trying to add a range that intersects with another range from selection.',\n\t\t\t\t\t{ addedRange: range, intersectingRange: storedRange }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis._ranges.push( Range.createFromRange( range ) );\n\t}\n}\n\nmix( Selection, EmitterMixin );\n\n/**\n * Fired whenever selection ranges are changed through {@link ~Selection Selection API}.\n *\n * @event change\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/selection.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals window, Text */\n\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * Set of utils related to block and inline fillers handling.\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 can not 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}.\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~Renderer renderer} and are not present in the\n * view.\n *\n * @module engine/view/filler\n */\n\n/**\n * `<br> filler creator. This is a function which creates `<br data-cke-filler=\"true\">` element.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~NBSP_FILLER\n * @function\n */\nexport const BR_FILLER = domDocument => {\n\tconst fillerBr = domDocument.createElement( 'br' );\n\tfillerBr.dataset.ckeFiller = true;\n\n\treturn fillerBr;\n};\n\n/**\n * Non-breaking space filler creator. This is a function which creates `&nbsp;` text node.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~BR_FILLER\n * @function\n */\nexport const NBSP_FILLER = domDocument => domDocument.createTextNode( '\\u00A0' );\n\n/**\n * Length of the {@link module:engine/view/filler~INLINE_FILLER INLINE_FILLER}.\n */\nexport const INLINE_FILLER_LENGTH = 7;\n\n/**\n * Inline filler which is sequence of the zero width spaces.\n */\nexport let INLINE_FILLER = '';\n\nfor ( let i = 0; i < INLINE_FILLER_LENGTH; i++ ) {\n\tINLINE_FILLER += '\\u200b';\n}\n\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 *\t\tstartsWithFiller( document.createTextNode( INLINE_FILLER ) ); // true\n *\t\tstartsWithFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // true\n *\t\tstartsWithFiller( document.createTextNode( 'foo' ) ); // false\n *\t\tstartsWithFiller( document.createElement( 'p' ) ); // false\n *\n * @param {Node} domNode DOM node.\n * @returns {Boolean} True if the text node starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */\nexport function startsWithFiller( domNode ) {\n\treturn ( domNode instanceof Text ) && ( domNode.data.substr( 0, INLINE_FILLER_LENGTH ) === INLINE_FILLER );\n}\n\n/**\n * Checks if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n *\n *\t\tisInlineFiller( document.createTextNode( INLINE_FILLER ) ); // true\n *\t\tisInlineFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // false\n *\n * @param {Text} domText DOM text node.\n * @returns {Boolean} True if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */\nexport function isInlineFiller( domText ) {\n\treturn domText.data.length == INLINE_FILLER_LENGTH && startsWithFiller( domText );\n}\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 *\t\tgetDataWithoutFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ) == 'foo' // true\n *\t\tgetDataWithoutFiller( document.createTextNode( 'foo' ) ) == 'foo' // true\n *\n * @param {Text} domText DOM text node, possible with inline filler.\n * @returns {String} Data without filler.\n */\nexport function getDataWithoutFiller( domText ) {\n\tif ( startsWithFiller( domText ) ) {\n\t\treturn domText.data.slice( INLINE_FILLER_LENGTH );\n\t} else {\n\t\treturn domText.data;\n\t}\n}\n\n// Cache block fillers templates to improve performance.\nconst templateBlockFillers = new WeakMap();\n\n/**\n * Checks if the node is an instance of the block filler of the given type.\n *\n *\t\tconst brFillerInstance = BR_FILLER( document );\n *\t\tisBlockFiller( brFillerInstance, BR_FILLER ); // true\n *\n * @param {Node} domNode DOM node to check.\n * @param {Function} blockFiller Block filler creator.\n * @returns {Boolean} True if text node contains only {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */\nexport function isBlockFiller( domNode, blockFiller ) {\n\tlet templateBlockFiller = templateBlockFillers.get( blockFiller );\n\n\tif ( !templateBlockFiller ) {\n\t\ttemplateBlockFiller = blockFiller( window.document );\n\t\ttemplateBlockFillers.set( blockFiller, templateBlockFiller );\n\t}\n\n\treturn domNode.isEqualNode( templateBlockFiller );\n}\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 {module:engine/view/document~Document} document Document instance we should inject quirks handling on.\n */\nexport function injectQuirksHandling( document ) {\n\tdocument.on( 'keydown', jumpOverInlineFiller );\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.\nfunction jumpOverInlineFiller( evt, data ) {\n\tif ( data.keyCode == keyCodes.arrowleft ) {\n\t\tconst domSelection = data.domTarget.ownerDocument.defaultView.getSelection();\n\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\n\t\t\tif ( startsWithFiller( domParent ) && domOffset <= INLINE_FILLER_LENGTH ) {\n\t\t\t\tdomSelection.collapse( domParent, 0 );\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/filler.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/diff\n */\n\n// The following code is based on the \"O(NP) Sequence Comparison Algorithm\"\n// by Sun Wu, Udi Manber, Gene Myers, Webb Miller.\n\n/**\n * Calculates the difference between two arrays or strings producing an array containing a list of changes\n * necessary to transform input into output.\n *\n *\t\tdiff( 'aba', 'acca' ); // [ 'equal', 'insert', 'insert', 'delete', 'equal' ]\n *\n * @param {Array|String} a Input array or string.\n * @param {Array|String} b Output array or string.\n * @param {Function} [cmp] Optional function used to compare array values, by default === is used.\n * @returns {Array} Array of changes.\n */\nexport default function diff( a, b, cmp ) {\n\t// Set the comparator function.\n\tcmp = cmp || function( a, b ) {\n\t\treturn a === b;\n\t};\n\n\t// Temporary action type statics.\n\tlet _insert, _delete;\n\n\t// Swapped the arrays to use the shorter one as the first one.\n\tif ( b.length < a.length ) {\n\t\tconst tmp = a;\n\n\t\ta = b;\n\t\tb = tmp;\n\n\t\t// We swap the action types as well.\n\t\t_insert = 'delete';\n\t\t_delete = 'insert';\n\t} else {\n\t\t_insert = 'insert';\n\t\t_delete = 'delete';\n\t}\n\n\tconst m = a.length;\n\tconst n = b.length;\n\tconst delta = n - m;\n\n\t// Edit scripts, for each diagonal.\n\tconst es = {};\n\t// Furthest points, the furthest y we can get on each diagonal.\n\tconst fp = {};\n\n\tfunction snake( k ) {\n\t\t// We use -1 as an alternative below to handle initial values ( instead of filling the fp with -1 first ).\n\t\t// Furthest points (y) on the diagonal below k.\n\t\tconst y1 = ( fp[ k - 1 ] !== undefined ? fp[ k - 1 ] : -1 ) + 1;\n\t\t// Furthest points (y) on the diagonal above k.\n\t\tconst y2 = fp[ k + 1 ] !== undefined ? fp[ k + 1 ] : -1;\n\t\t// The way we should go to get further.\n\t\tconst dir = y1 > y2 ? -1 : 1;\n\n\t\t// Clone previous changes array (if any).\n\t\tif ( es[ k + dir ] ) {\n\t\t\tes[ k ] = es[ k + dir ].slice( 0 );\n\t\t}\n\n\t\t// Create changes array.\n\t\tif ( !es[ k ] ) {\n\t\t\tes[ k ] = [];\n\t\t}\n\n\t\t// Push the action.\n\t\tes[ k ].push( y1 > y2 ? _insert : _delete );\n\n\t\t// Set the beginning coordinates.\n\t\tlet y = Math.max( y1, y2 );\n\t\tlet x = y - k;\n\n\t\t// Traverse the diagonal as long as the values match.\n\t\twhile ( x < m && y < n && cmp( a[ x ], b[ y ] ) ) {\n\t\t\tx++;\n\t\t\ty++;\n\t\t\t// Push no change action.\n\t\t\tes[ k ].push( 'equal' );\n\t\t}\n\n\t\treturn y;\n\t}\n\n\tlet p = 0;\n\tlet k;\n\n\t// Traverse the graph until we reach the end of the longer string.\n\tdo {\n\t\t// Updates furthest points and edit scripts for diagonals below delta.\n\t\tfor ( k = -p; k < delta; k++ ) {\n\t\t\tfp[ k ] = snake( k );\n\t\t}\n\n\t\t// Updates furthest points and edit scripts for diagonals above delta.\n\t\tfor ( k = delta + p; k > delta; k-- ) {\n\t\t\tfp[ k ] = snake( k );\n\t\t}\n\n\t\t// Updates furthest point and edit script for the delta diagonal.\n\t\t// note that the delta diagonal is the one which goes through the sink (m, n).\n\t\tfp[ delta ] = snake( delta );\n\n\t\tp++;\n\t} while ( fp[ delta ] !== n );\n\n\t// Return the final list of edit changes.\n\t// We remove the first item that represents the action for the injected nulls.\n\treturn es[ delta ].slice( 1 );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/diff.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/insertat\n */\n\n/**\n * Inserts node to the parent at given index.\n *\n * @param {Element} parentElement Parent element.\n * @param {Number} index Insertions index.\n * @param {Node} nodeToInsert Node to insert.\n */\nexport default function insertAt( parentElement, index, nodeToInsert ) {\n\tparentElement.insertBefore( nodeToInsert, parentElement.childNodes[ index ] || null );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/insertat.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/remove\n */\n\n/**\n * Removes given node from parent.\n *\n * @param {Node} node Node to remove.\n */\nexport default function remove( node ) {\n\tconst parent = node.parentNode;\n\n\tif ( parent ) {\n\t\tparent.removeChild( node );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/remove.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/renderer\n */\n\nimport ViewText from './text';\nimport ViewPosition from './position';\nimport { INLINE_FILLER, INLINE_FILLER_LENGTH, startsWithFiller, isInlineFiller, isBlockFiller } from './filler';\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport diff from '@ckeditor/ckeditor5-utils/src/diff';\nimport insertAt from '@ckeditor/ckeditor5-utils/src/dom/insertat';\nimport remove from '@ckeditor/ckeditor5-utils/src/dom/remove';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Renderer updates DOM structure and selection, to make them a reflection of the view structure and selection.\n *\n * View nodes which may need to be rendered needs to be {@link module:engine/view/renderer~Renderer#markToSync marked}.\n * Then, on {@link module:engine/view/renderer~Renderer#render render}, renderer compares view nodes with DOM nodes\n * in order to check which ones really need to be refreshed. Finally, it creates DOM nodes from these view nodes,\n * {@link module:engine/view/domconverter~DomConverter#bindElements binds} them and inserts into the DOM tree.\n *\n * Every time {@link module:engine/view/renderer~Renderer#render render} is called, renderer additionally checks if\n * {@link module:engine/view/renderer~Renderer#selection selection} needs update and updates it if so.\n *\n * Renderer uses {@link module:engine/view/domconverter~DomConverter} to transform and bind nodes.\n */\nexport default class Renderer {\n\t/**\n\t * Creates a renderer instance.\n\t *\n\t * @param {module:engine/view/domconverter~DomConverter} domConverter Converter instance.\n\t * @param {module:engine/view/selection~Selection} selection View selection.\n\t */\n\tconstructor( domConverter, selection ) {\n\t\t/**\n\t\t * Set of DOM Documents instances.\n\t\t *\n\t\t * @member {Set.<Document>}\n\t\t */\n\t\tthis.domDocuments = new Set();\n\n\t\t/**\n\t\t * Converter instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/domconverter~DomConverter}\n\t\t */\n\t\tthis.domConverter = domConverter;\n\n\t\t/**\n\t\t * Set of nodes which attributes changed and may need to be rendered.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set.<module:engine/view/node~Node>}\n\t\t */\n\t\tthis.markedAttributes = new Set();\n\n\t\t/**\n\t\t * Set of elements which child lists changed and may need to be rendered.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set.<module:engine/view/node~Node>}\n\t\t */\n\t\tthis.markedChildren = new Set();\n\n\t\t/**\n\t\t * Set of text nodes which text data changed and may need to be rendered.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set.<module:engine/view/node~Node>}\n\t\t */\n\t\tthis.markedTexts = new Set();\n\n\t\t/**\n\t\t * View selection. Renderer updates DOM selection based on the view selection.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/selection~Selection}\n\t\t */\n\t\tthis.selection = selection;\n\n\t\t/**\n\t\t * The text node in which the inline filler was rendered.\n\t\t *\n\t\t * @private\n\t\t * @member {Text}\n\t\t */\n\t\tthis._inlineFiller = null;\n\n\t\t/**\n\t\t * Indicates if the view document is focused and selection can be rendered. Selection will not be rendered if\n\t\t * this is set to `false`.\n\t\t *\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.isFocused = false;\n\n\t\t/**\n\t\t * DOM element containing fake selection.\n\t\t *\n\t\t * @private\n\t\t * @type {null|HTMLElement}\n\t\t */\n\t\tthis._fakeSelectionContainer = null;\n\t}\n\n\t/**\n\t * Mark node to be synchronized.\n\t *\n\t * Note that only view nodes which 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 {module:engine/view/document~ChangeType} type Type of the change.\n\t * @param {module:engine/view/node~Node} node Node to be marked.\n\t */\n\tmarkToSync( type, node ) {\n\t\tif ( type === 'text' ) {\n\t\t\tif ( this.domConverter.mapViewToDom( node.parent ) ) {\n\t\t\t\tthis.markedTexts.add( node );\n\t\t\t}\n\t\t} else {\n\t\t\t// If the node has no DOM element it is not rendered yet,\n\t\t\t// its children/attributes do not need to be marked to be sync.\n\t\t\tif ( !this.domConverter.mapViewToDom( node ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( type === 'attributes' ) {\n\t\t\t\tthis.markedAttributes.add( node );\n\t\t\t} else if ( type === 'children' ) {\n\t\t\t\tthis.markedChildren.add( node );\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * Unknown type passed to Renderer.markToSync.\n\t\t\t\t *\n\t\t\t\t * @error renderer-unknown-type\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'view-renderer-unknown-type: Unknown type passed to Renderer.markToSync.' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Render method checks {@link #markedAttributes},\n\t * {@link #markedChildren} and {@link #markedTexts} and updates all\n\t * nodes which need to be updated. Then it clears all three sets. Also, every time render is called it compares and\n\t * if needed updates the selection.\n\t *\n\t * Renderer tries not to break 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 * For attributes it adds new attributes to DOM elements, updates values and removes\n\t * attributes which do not exist in the view element.\n\t *\n\t * For text nodes it updates the text string if it is different. Note that if parent element is marked as an element\n\t * which changed child list, text node update will not be done, because it may not be possible to\n\t * {@link module:engine/view/domconverter~DomConverter#findCorrespondingDomText find a corresponding DOM text}.\n\t * The change will be handled in the parent element.\n\t *\n\t * For elements, which child lists have changed, it calculates a {@link module:utils/diff~diff} and adds or removes children which have\n\t * changed.\n\t *\n\t * Rendering also handles {@link module:engine/view/filler fillers}. Especially, it checks if the inline filler is needed\n\t * at selection position and adds or removes it. To prevent breaking text composition inline filler will not be\n\t * removed as long selection is in the text node which needed it at first.\n\t */\n\trender() {\n\t\tlet inlineFillerPosition;\n\n\t\t// There was inline filler rendered in the DOM but it's not\n\t\t// at the selection position any more, so we can remove it\n\t\t// (cause even if it's needed, it must be placed in another location).\n\t\tif ( this._inlineFiller && !this._isSelectionInInlineFiller() ) {\n\t\t\tthis._removeInlineFiller();\n\t\t}\n\n\t\t// If we've got the filler, let's try to guess its position in the view.\n\t\tif ( this._inlineFiller ) {\n\t\t\tinlineFillerPosition = this._getInlineFillerPosition();\n\t\t}\n\t\t// Otherwise, if it's needed, create it at the selection position.\n\t\telse if ( this._needsInlineFillerAtSelection() ) {\n\t\t\tinlineFillerPosition = this.selection.getFirstPosition();\n\n\t\t\t// Do not use `markToSync` so it will be added even if the parent is already added.\n\t\t\tthis.markedChildren.add( inlineFillerPosition.parent );\n\t\t}\n\n\t\tfor ( const node of this.markedTexts ) {\n\t\t\tif ( !this.markedChildren.has( node.parent ) && this.domConverter.mapViewToDom( node.parent ) ) {\n\t\t\t\tthis._updateText( node, { inlineFillerPosition } );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const element of this.markedAttributes ) {\n\t\t\tthis._updateAttrs( element );\n\t\t}\n\n\t\tfor ( const element of this.markedChildren ) {\n\t\t\tthis._updateChildren( element, { inlineFillerPosition } );\n\t\t}\n\n\t\t// Check whether the inline filler is required and where it really is in the DOM.\n\t\t// At this point in most cases it will be in the DOM, but there are exceptions.\n\t\t// For example, if the inline filler was deep in the created DOM structure, it will not be created.\n\t\t// Similarly, if it was removed at the beginning of this function and then neither text nor children were updated,\n\t\t// it will not be present.\n\t\t// Fix those and similar scenarios.\n\t\tif ( inlineFillerPosition ) {\n\t\t\tconst fillerDomPosition = this.domConverter.viewPositionToDom( inlineFillerPosition );\n\t\t\tconst domDocument = fillerDomPosition.parent.ownerDocument;\n\n\t\t\tif ( !startsWithFiller( fillerDomPosition.parent ) ) {\n\t\t\t\t// Filler has not been created at filler position. Create it now.\n\t\t\t\tthis._inlineFiller = this._addInlineFiller( domDocument, fillerDomPosition.parent, fillerDomPosition.offset );\n\t\t\t} else {\n\t\t\t\t// Filler has been found, save it.\n\t\t\t\tthis._inlineFiller = fillerDomPosition.parent;\n\t\t\t}\n\t\t} else {\n\t\t\t// There is no filler needed.\n\t\t\tthis._inlineFiller = null;\n\t\t}\n\n\t\tthis._updateSelection();\n\t\tthis._updateFocus();\n\n\t\tthis.markedTexts.clear();\n\t\tthis.markedAttributes.clear();\n\t\tthis.markedChildren.clear();\n\t}\n\n\t/**\n\t * Adds inline filler at given position.\n\t *\n\t * The position can be given as an array of DOM nodes and an offset in that array,\n\t * or a DOM parent element and offset in that element.\n\t *\n\t * @private\n\t * @param {Document} domDocument\n\t * @param {Element|Array.<Node>} domParentOrArray\n\t * @param {Number} offset\n\t * @returns {Text} The DOM text node that contains inline filler.\n\t */\n\t_addInlineFiller( domDocument, domParentOrArray, offset ) {\n\t\tconst childNodes = domParentOrArray instanceof Array ? domParentOrArray : domParentOrArray.childNodes;\n\t\tconst nodeAfterFiller = childNodes[ offset ];\n\n\t\tif ( this.domConverter.isText( nodeAfterFiller ) ) {\n\t\t\tnodeAfterFiller.data = INLINE_FILLER + nodeAfterFiller.data;\n\n\t\t\treturn nodeAfterFiller;\n\t\t} else {\n\t\t\tconst fillerNode = domDocument.createTextNode( INLINE_FILLER );\n\n\t\t\tif ( Array.isArray( domParentOrArray ) ) {\n\t\t\t\tchildNodes.splice( offset, 0, fillerNode );\n\t\t\t} else {\n\t\t\t\tinsertAt( domParentOrArray, offset, fillerNode );\n\t\t\t}\n\n\t\t\treturn fillerNode;\n\t\t}\n\t}\n\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's needed,\n\t * it's somewhere at the selection postion.\n\t *\n\t * Note: we cannot restore the filler position 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 * @private\n\t * @returns {module:engine/view/position~Position}\n\t */\n\t_getInlineFillerPosition() {\n\t\tconst firstPos = this.selection.getFirstPosition();\n\n\t\tif ( firstPos.parent.is( 'text' ) ) {\n\t\t\treturn ViewPosition.createBefore( this.selection.getFirstPosition().parent );\n\t\t} else {\n\t\t\treturn firstPos;\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` if the selection hasn't 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 does not\n\t * left the filler's text node. E.g. the user can be in the middle of a composition so it should not be touched.\n\t *\n\t * @private\n\t * @returns {Boolean} 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 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Note, we can't check if selection's position equals position of the\n\t\t// this._inlineFiller node, because of #663. We may not be able to calculate\n\t\t// the filler's position in the view at this stage.\n\t\t// Instead, we check it the other way whether selection is anchored in\n\t\t// that text node or next to it.\n\n\t\t// Possible options are:\n\t\t// \"FILLER{}\"\n\t\t// \"FILLERadded-text{}\"\n\t\tconst selectionPosition = this.selection.getFirstPosition();\n\t\tconst position = this.domConverter.viewPositionToDom( selectionPosition );\n\n\t\tif ( position && this.domConverter.isText( position.parent ) && startsWithFiller( position.parent ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Removes the inline filler.\n\t *\n\t * @private\n\t */\n\t_removeInlineFiller() {\n\t\tconst domFillerNode = this._inlineFiller;\n\n\t\t// Something weird happened and the stored node doesn't contain the filler's text.\n\t\tif ( !startsWithFiller( domFillerNode ) ) {\n\t\t\t/**\n\t\t\t * The inline filler node was lost. Most likely, something overwrote the filler text node\n\t\t\t * in the DOM.\n\t\t\t *\n\t\t\t * @error view-renderer-filler-was-lost\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-renderer-filler-was-lost: The inline filler node was lost.' );\n\t\t}\n\n\t\tif ( isInlineFiller( domFillerNode ) ) {\n\t\t\tdomFillerNode.parentNode.removeChild( domFillerNode );\n\t\t} else {\n\t\t\tdomFillerNode.data = domFillerNode.data.substr( INLINE_FILLER_LENGTH );\n\t\t}\n\n\t\tthis._inlineFiller = null;\n\t}\n\n\t/**\n\t * Checks if the inline {@link module:engine/view/filler filler} should be added.\n\t *\n\t * @private\n\t * @returns {Boolean} True if the inline fillers should be added.\n\t */\n\t_needsInlineFillerAtSelection() {\n\t\tif ( this.selection.rangeCount != 1 || !this.selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst selectionPosition = this.selection.getFirstPosition();\n\t\tconst selectionParent = selectionPosition.parent;\n\t\tconst selectionOffset = selectionPosition.offset;\n\n\t\t// If there is no DOM root we do not care about fillers.\n\t\tif ( !this.domConverter.mapViewToDom( selectionParent.root ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !( selectionParent.is( 'element' ) ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Prevent adding inline filler inside elements with contenteditable=false.\n\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/1170\n\t\tif ( !_isEditable( selectionParent ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// We have block filler, we do not need inline one.\n\t\tif ( selectionOffset === selectionParent.getFillerOffset() ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst nodeBefore = selectionPosition.nodeBefore;\n\t\tconst nodeAfter = selectionPosition.nodeAfter;\n\n\t\tif ( nodeBefore instanceof ViewText || nodeAfter instanceof ViewText ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks if text needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t * @param {module:engine/view/text~Text} viewText View text to update.\n\t * @param {Object} options\n\t * @param {module:engine/view/position~Position} options.inlineFillerPosition The position on which the inline\n\t * filler should be rendered.\n\t */\n\t_updateText( viewText, options ) {\n\t\tconst domText = this.domConverter.findCorrespondingDomText( viewText );\n\t\tconst newDomText = this.domConverter.viewToDom( viewText, domText.ownerDocument );\n\n\t\tconst actualText = domText.data;\n\t\tlet expectedText = newDomText.data;\n\n\t\tconst filler = options.inlineFillerPosition;\n\n\t\tif ( filler && filler.parent == viewText.parent && filler.offset == viewText.index ) {\n\t\t\texpectedText = INLINE_FILLER + expectedText;\n\t\t}\n\n\t\tif ( actualText != expectedText ) {\n\t\t\tdomText.data = expectedText;\n\t\t}\n\t}\n\n\t/**\n\t * Checks if attributes list needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} viewElement View element to update.\n\t */\n\t_updateAttrs( viewElement ) {\n\t\tconst domElement = this.domConverter.mapViewToDom( viewElement );\n\t\tconst domAttrKeys = Array.from( domElement.attributes ).map( attr => attr.name );\n\t\tconst viewAttrKeys = viewElement.getAttributeKeys();\n\n\t\t// Add or overwrite attributes.\n\t\tfor ( const key of viewAttrKeys ) {\n\t\t\tdomElement.setAttribute( key, viewElement.getAttribute( key ) );\n\t\t}\n\n\t\t// Remove from DOM attributes which do not exists in the view.\n\t\tfor ( const key of domAttrKeys ) {\n\t\t\tif ( !viewElement.hasAttribute( key ) ) {\n\t\t\t\tdomElement.removeAttribute( key );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if elements child list needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} viewElement View element to update.\n\t * @param {Object} options\n\t * @param {module:engine/view/position~Position} options.inlineFillerPosition The position on which the inline\n\t * filler should be rendered.\n\t */\n\t_updateChildren( viewElement, options ) {\n\t\tconst domConverter = this.domConverter;\n\t\tconst domElement = domConverter.mapViewToDom( viewElement );\n\n\t\tif ( !domElement ) {\n\t\t\t// If there is no `domElement` it means that it was already removed from DOM.\n\t\t\t// There is no need to update it. It will be updated when re-inserted.\n\t\t\treturn;\n\t\t}\n\n\t\tconst domDocument = domElement.ownerDocument;\n\t\tconst filler = options.inlineFillerPosition;\n\t\tconst actualDomChildren = domElement.childNodes;\n\t\tconst expectedDomChildren = Array.from( domConverter.viewChildrenToDom( viewElement, domDocument, { bind: true } ) );\n\n\t\t// Inline filler element has to be created during children update because we need it to diff actual dom\n\t\t// elements with expected dom elements. We need inline filler in expected dom elements so we won't re-render\n\t\t// text node if it is not necessary.\n\t\tif ( filler && filler.parent == viewElement ) {\n\t\t\tthis._addInlineFiller( domDocument, expectedDomChildren, filler.offset );\n\t\t}\n\n\t\tconst actions = diff( actualDomChildren, expectedDomChildren, sameNodes );\n\n\t\tlet i = 0;\n\t\tconst nodesToUnbind = new Set();\n\n\t\tfor ( const action of actions ) {\n\t\t\tif ( action === 'insert' ) {\n\t\t\t\tinsertAt( domElement, i, expectedDomChildren[ i ] );\n\t\t\t\ti++;\n\t\t\t} else if ( action === 'delete' ) {\n\t\t\t\tnodesToUnbind.add( actualDomChildren[ i ] );\n\t\t\t\tremove( actualDomChildren[ i ] );\n\t\t\t} else { // 'equal'\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\t// Unbind removed nodes. When node does not have a parent it means that it was removed from DOM tree during\n\t\t// comparision with the expected DOM. We don't need to check child nodes, because if child node was reinserted,\n\t\t// it was moved to DOM tree out of the removed node.\n\t\tfor ( const node of nodesToUnbind ) {\n\t\t\tif ( !node.parentNode ) {\n\t\t\t\tthis.domConverter.unbindDomElement( node );\n\t\t\t}\n\t\t}\n\n\t\tfunction sameNodes( actualDomChild, expectedDomChild ) {\n\t\t\t// Elements.\n\t\t\tif ( actualDomChild === expectedDomChild ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t// Texts.\n\t\t\telse if ( domConverter.isText( actualDomChild ) && domConverter.isText( expectedDomChild ) ) {\n\t\t\t\treturn actualDomChild.data === expectedDomChild.data;\n\t\t\t}\n\t\t\t// Block fillers.\n\t\t\telse if ( isBlockFiller( actualDomChild, domConverter.blockFiller ) &&\n\t\t\t\tisBlockFiller( expectedDomChild, domConverter.blockFiller ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Not matching types.\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Checks if selection needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t */\n\t_updateSelection() {\n\t\t// If there is no selection - remove DOM and fake selections.\n\t\tif ( this.selection.rangeCount === 0 ) {\n\t\t\tthis._removeDomSelection();\n\t\t\tthis._removeFakeSelection();\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst domRoot = this.domConverter.mapViewToDom( this.selection.editableElement );\n\n\t\t// Do nothing if there is no focus, or there is no DOM element corresponding to selection's editable element.\n\t\tif ( !this.isFocused || !domRoot ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Render selection.\n\t\tif ( this.selection.isFake ) {\n\t\t\tthis._updateFakeSelection( domRoot );\n\t\t} else {\n\t\t\tthis._removeFakeSelection();\n\t\t\tthis._updateDomSelection( domRoot );\n\t\t}\n\t}\n\n\t/**\n\t * Updates fake selection.\n\t *\n\t * @private\n\t * @param {HTMLElement} domRoot Valid DOM root where fake selection container should be added.\n\t */\n\t_updateFakeSelection( domRoot ) {\n\t\tconst domDocument = domRoot.ownerDocument;\n\n\t\t// Create fake selection container if one does not exist.\n\t\tif ( !this._fakeSelectionContainer ) {\n\t\t\tthis._fakeSelectionContainer = domDocument.createElement( 'div' );\n\t\t\tthis._fakeSelectionContainer.style.position = 'fixed';\n\t\t\tthis._fakeSelectionContainer.style.top = 0;\n\t\t\tthis._fakeSelectionContainer.style.left = '-9999px';\n\t\t\tthis._fakeSelectionContainer.appendChild( domDocument.createTextNode( '\\u00A0' ) );\n\t\t}\n\n\t\t// Add fake container if not already added.\n\t\tif ( !this._fakeSelectionContainer.parentElement ) {\n\t\t\tdomRoot.appendChild( this._fakeSelectionContainer );\n\t\t}\n\n\t\t// Update contents.\n\t\tconst content = this.selection.fakeSelectionLabel || '\\u00A0';\n\t\tthis._fakeSelectionContainer.firstChild.data = content;\n\n\t\t// Update selection.\n\t\tconst domSelection = domDocument.getSelection();\n\t\tdomSelection.removeAllRanges();\n\n\t\tconst domRange = domDocument.createRange();\n\t\tdomRange.selectNodeContents( this._fakeSelectionContainer );\n\t\tdomSelection.addRange( domRange );\n\n\t\t// Bind fake selection container with current selection.\n\t\tthis.domConverter.bindFakeSelection( this._fakeSelectionContainer, this.selection );\n\t}\n\n\t/**\n\t * Updates DOM selection.\n\t *\n\t * @private\n\t * @param {HTMLElement} domRoot Valid DOM root where DOM selection should be rendered.\n\t */\n\t_updateDomSelection( domRoot ) {\n\t\tconst domSelection = domRoot.ownerDocument.defaultView.getSelection();\n\n\t\t// Let's check whether DOM selection needs updating at all.\n\t\tif ( !this._domSelectionNeedsUpdate( domSelection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Multi-range selection is not available in most browsers, and, at least in Chrome, trying to\n\t\t// set such selection, that is not continuous, throws an error. Because of that, we will just use anchor\n\t\t// and focus of view selection.\n\t\t// Since we are not supporting multi-range selection, we also do not need to check if proper editable is\n\t\t// selected. If there is any editable selected, it is okay (editable is taken from selection anchor).\n\t\tconst anchor = this.domConverter.viewPositionToDom( this.selection.anchor );\n\t\tconst focus = this.domConverter.viewPositionToDom( this.selection.focus );\n\n\t\tdomSelection.collapse( anchor.parent, anchor.offset );\n\t\tdomSelection.extend( focus.parent, focus.offset );\n\t}\n\n\t/**\n\t * Checks whether given DOM selection needs to be updated.\n\t *\n\t * @private\n\t * @param {Selection} domSelection DOM selection to check.\n\t * @returns {Boolean}\n\t */\n\t_domSelectionNeedsUpdate( domSelection ) {\n\t\tif ( !this.domConverter.isDomSelectionCorrect( domSelection ) ) {\n\t\t\t// Current DOM selection is in incorrect position. We need to update it.\n\t\t\treturn true;\n\t\t}\n\n\t\tconst oldViewSelection = domSelection && this.domConverter.domSelectionToView( domSelection );\n\n\t\tif ( oldViewSelection && this.selection.isEqual( oldViewSelection ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If selection is not collapsed, it does not need to be updated if it is similar.\n\t\tif ( !this.selection.isCollapsed && this.selection.isSimilar( oldViewSelection ) ) {\n\t\t\t// Selection did not changed and is correct, do not update.\n\t\t\treturn false;\n\t\t}\n\n\t\t// Selections are not similar.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Removes DOM selection.\n\t *\n\t * @private\n\t */\n\t_removeDomSelection() {\n\t\tfor ( const doc of this.domDocuments ) {\n\t\t\tconst domSelection = doc.getSelection();\n\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\n\t\t\t\tif ( activeDomElement && viewElement ) {\n\t\t\t\t\tdoc.getSelection().removeAllRanges();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes fake selection.\n\t *\n\t * @private\n\t */\n\t_removeFakeSelection() {\n\t\tconst container = this._fakeSelectionContainer;\n\n\t\tif ( container ) {\n\t\t\tcontainer.remove();\n\t\t}\n\t}\n\n\t/**\n\t * Checks if focus needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t */\n\t_updateFocus() {\n\t\tif ( this.isFocused ) {\n\t\t\tconst editable = this.selection.editableElement;\n\n\t\t\tif ( editable ) {\n\t\t\t\tthis.domConverter.focus( editable );\n\t\t\t}\n\t\t}\n\t}\n}\n\nmix( Renderer, ObservableMixin );\n\n// Checks if provided element is editable.\n//\n// @private\n// @param {module:engine/view/element~Element} element\n// @returns {Boolean}\nfunction _isEditable( element ) {\n\tif ( element.getAttribute( 'contenteditable' ) == 'false' ) {\n\t\treturn false;\n\t}\n\n\tconst parent = element.findAncestor( element => element.hasAttribute( 'contenteditable' ) );\n\n\treturn !parent || parent.getAttribute( 'contenteditable' ) == 'true';\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/renderer.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals window, document */\n\n/**\n * @module utils/dom/global\n */\n\n/**\n * A helper (module) giving an access to the global DOM objects such as `window` and\n * `document`. Accessing these objects using this helper allows easy and bulletproof\n * testing, i.e. stubbing native properties:\n *\n *\t\timport global from 'ckeditor5/utils/dom/global.js';\n *\n *\t\t// This stub will work for any code using global module.\n *\t\ttestUtils.sinon.stub( global, 'window', {\n *\t\t\tinnerWidth: 10000\n *\t\t} );\n *\n *\t\tconsole.log( global.window.innerWidth );\n */\nexport default { window, document };\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/global.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/indexof\n */\n\n/**\n * Returns index of the node in the parent element.\n *\n * @param {Node} node Node which index is tested.\n * @returns {Number} Index of the node in the parent element. Returns 0 if node has no parent.\n */\nexport default function indexOf( node ) {\n\tlet index = 0;\n\n\twhile ( node.previousSibling ) {\n\t\tnode = node.previousSibling;\n\t\tindex++;\n\t}\n\n\treturn index;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/indexof.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals Node */\n\n/**\n * @module utils/dom/getancestors\n */\n\n/**\n * Returns all ancestors of given DOM node, starting from the top-most (root). Includes the given node itself. If the\n * node is a part of `DocumentFragment` that `DocumentFragment` will be returned. In contrary, if the node is\n * appended to a `Document`, that `Document` will not be returned (algorithms operating on DOM tree care for `Document#documentElement`\n * at most, which will be returned).\n *\n * @param {Node} node DOM node.\n * @returns {Array.<Node|DocumentFragment>} Array of given `node` parents.\n */\nexport default function getAncestors( node ) {\n\tconst nodes = [];\n\n\t// We are interested in `Node`s `DocumentFragment`s only.\n\twhile ( node && node.nodeType != Node.DOCUMENT_NODE ) {\n\t\tnodes.unshift( node );\n\t\tnode = node.parentNode;\n\t}\n\n\treturn nodes;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/getancestors.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/getcommonancestor\n */\n\nimport getAncestors from './getancestors';\n\n/**\n * Searches and returns the lowest common ancestor of two given nodes.\n *\n * @param {Node} nodeA First node.\n * @param {Node} nodeB Second node.\n * @returns {Node|DocumentFragment|Document|null} Lowest common ancestor of both nodes or `null` if nodes do not have a common ancestor.\n */\nexport default function getCommonAncestor( nodeA, nodeB ) {\n\tconst ancestorsA = getAncestors( nodeA );\n\tconst ancestorsB = getAncestors( nodeB );\n\n\tlet i = 0;\n\n\t// It does not matter which array is shorter.\n\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\ti++;\n\t}\n\n\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/getcommonancestor.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/domconverter\n */\n\n/* globals document, Node, NodeFilter */\n\nimport ViewText from './text';\nimport ViewElement from './element';\nimport ViewPosition from './position';\nimport ViewRange from './range';\nimport ViewSelection from './selection';\nimport ViewDocumentFragment from './documentfragment';\nimport ViewTreeWalker from './treewalker';\nimport { BR_FILLER, INLINE_FILLER_LENGTH, isBlockFiller, isInlineFiller, startsWithFiller, getDataWithoutFiller } from './filler';\n\nimport global from '@ckeditor/ckeditor5-utils/src/dom/global';\nimport indexOf from '@ckeditor/ckeditor5-utils/src/dom/indexof';\nimport getAncestors from '@ckeditor/ckeditor5-utils/src/dom/getancestors';\nimport getCommonAncestor from '@ckeditor/ckeditor5-utils/src/dom/getcommonancestor';\n\n/**\n * DomConverter is a set of tools to do transformations between DOM nodes and view nodes. It also handles\n * {@link module:engine/view/domconverter~DomConverter#bindElements binding} these nodes.\n *\n * DomConverter does not check which nodes should be rendered (use {@link module:engine/view/renderer~Renderer}), does not keep a\n * state of a tree nor keeps synchronization between tree view and DOM tree (use {@link module:engine/view/document~Document}).\n *\n * DomConverter keeps DOM elements to View element bindings, so when the converter will be destroyed, the binding will\n * be lost. Two converters will keep separate binding maps, so one tree view can be bound with two DOM trees.\n */\nexport default class DomConverter {\n\t/**\n\t * Creates DOM converter.\n\t *\n\t * @param {Object} options Object with configuration options.\n\t * @param {Function} [options.blockFiller=module:engine/view/filler~BR_FILLER] Block filler creator.\n\t */\n\tconstructor( options = {} ) {\n\t\t// Using WeakMap prevent memory leaks: when the converter will be destroyed all referenced between View and DOM\n\t\t// will be removed. Also because it is a *Weak*Map when both view and DOM elements will be removed referenced\n\t\t// will be also removed, isn't it brilliant?\n\t\t//\n\t\t// Yes, PJ. It is.\n\t\t//\n\t\t// You guys so smart.\n\t\t//\n\t\t// I've been here. Seen stuff. Afraid of code now.\n\n\t\t/**\n\t\t * Block {@link module:engine/view/filler filler} creator, which is used to create all block fillers during the\n\t\t * view to DOM conversion and to recognize block fillers during the DOM to view conversion.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Function} module:engine/view/domconverter~DomConverter#blockFiller\n\t\t */\n\t\tthis.blockFiller = options.blockFiller || BR_FILLER;\n\n\t\t/**\n\t\t * Tag names of DOM `Element`s which are considered pre-formatted elements.\n\t\t *\n\t\t * @member {Array.<String>} module:engine/view/domconverter~DomConverter#preElements\n\t\t */\n\t\tthis.preElements = [ 'pre' ];\n\n\t\t/**\n\t\t * Tag names of DOM `Element`s which are considered block elements.\n\t\t *\n\t\t * @member {Array.<String>} module:engine/view/domconverter~DomConverter#blockElements\n\t\t */\n\t\tthis.blockElements = [ 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ];\n\n\t\t/**\n\t\t * DOM to View mapping.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap} module:engine/view/domconverter~DomConverter#_domToViewMapping\n\t\t */\n\t\tthis._domToViewMapping = new WeakMap();\n\n\t\t/**\n\t\t * View to DOM mapping.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap} module:engine/view/domconverter~DomConverter#_viewToDomMapping\n\t\t */\n\t\tthis._viewToDomMapping = new WeakMap();\n\n\t\t/**\n\t\t * Holds mapping between fake selection containers and corresponding view selections.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap} module:engine/view/domconverter~DomConverter#_fakeSelectionMapping\n\t\t */\n\t\tthis._fakeSelectionMapping = new WeakMap();\n\t}\n\n\t/**\n\t * Binds given DOM element that represents fake selection to {@link module:engine/view/selection~Selection view selection}.\n\t * View selection copy is stored and can be retrieved by {@link module:engine/view/domconverter~DomConverter#fakeSelectionToView}\n\t * method.\n\t *\n\t * @param {HTMLElement} domElement\n\t * @param {module:engine/view/selection~Selection} viewSelection\n\t */\n\tbindFakeSelection( domElement, viewSelection ) {\n\t\tthis._fakeSelectionMapping.set( domElement, ViewSelection.createFromSelection( viewSelection ) );\n\t}\n\n\t/**\n\t * Returns {@link module:engine/view/selection~Selection view selection} instance corresponding to given DOM element that represents\n\t * fake selection. Returns `undefined` if binding to given DOM element does not exists.\n\t *\n\t * @param {HTMLElement} domElement\n\t * @returns {module:engine/view/selection~Selection|undefined}\n\t */\n\tfakeSelectionToView( domElement ) {\n\t\treturn this._fakeSelectionMapping.get( domElement );\n\t}\n\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~DomConverter#mapDomToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#mapViewToDom}.\n\t *\n\t * @param {HTMLElement} domElement DOM element to bind.\n\t * @param {module:engine/view/element~Element} viewElement 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\n\t/**\n\t * Unbinds given `domElement` from the view element it was bound to. Unbinding is deep, meaning that all children of\n\t * `domElement` will be unbound too.\n\t *\n\t * @param {HTMLElement} domElement DOM element to unbind.\n\t */\n\tunbindDomElement( domElement ) {\n\t\tconst viewElement = this._domToViewMapping.get( domElement );\n\n\t\tif ( viewElement ) {\n\t\t\tthis._domToViewMapping.delete( domElement );\n\t\t\tthis._viewToDomMapping.delete( viewElement );\n\n\t\t\t// Use Array.from because of MS Edge (#923).\n\t\t\tfor ( const child of Array.from( domElement.childNodes ) ) {\n\t\t\t\tthis.unbindDomElement( child );\n\t\t\t}\n\t\t}\n\t}\n\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~DomConverter#mapDomToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#mapViewToDom}.\n\t *\n\t * @param {DocumentFragment} domFragment DOM document fragment to bind.\n\t * @param {module:engine/view/documentfragment~DocumentFragment} viewFragment 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\n\t/**\n\t * Converts view to DOM. 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.\n\t *\n\t * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} viewNode\n\t * View node or document fragment to transform.\n\t * @param {Document} domDocument Document which will be used to create DOM nodes.\n\t * @param {Object} [options] Conversion options.\n\t * @param {Boolean} [options.bind=false] Determines whether new elements will be bound.\n\t * @param {Boolean} [options.withChildren=true] If `true`, node's and document fragment's children will be converted too.\n\t * @returns {Node|DocumentFragment} Converted node or DocumentFragment.\n\t */\n\tviewToDom( viewNode, domDocument, options = {} ) {\n\t\tif ( viewNode.is( 'text' ) ) {\n\t\t\tconst textData = this._processDataFromViewText( viewNode );\n\n\t\t\treturn domDocument.createTextNode( textData );\n\t\t} else {\n\t\t\tif ( this.mapViewToDom( viewNode ) ) {\n\t\t\t\treturn this.mapViewToDom( viewNode );\n\t\t\t}\n\n\t\t\tlet domElement;\n\n\t\t\tif ( viewNode.is( 'documentFragment' ) ) {\n\t\t\t\t// Create DOM document fragment.\n\t\t\t\tdomElement = domDocument.createDocumentFragment();\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindDocumentFragments( domElement, viewNode );\n\t\t\t\t}\n\t\t\t} else if ( viewNode.is( 'uiElement' ) ) {\n\t\t\t\t// UIElement has its own render() method (see #799).\n\t\t\t\tdomElement = viewNode.render( domDocument );\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domElement, viewNode );\n\t\t\t\t}\n\n\t\t\t\treturn domElement;\n\t\t\t} else {\n\t\t\t\t// Create DOM element.\n\t\t\t\tdomElement = domDocument.createElement( viewNode.name );\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domElement, viewNode );\n\t\t\t\t}\n\n\t\t\t\t// Copy element's attributes.\n\t\t\t\tfor ( const key of viewNode.getAttributeKeys() ) {\n\t\t\t\t\tdomElement.setAttribute( key, viewNode.getAttribute( key ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( options.withChildren || options.withChildren === undefined ) {\n\t\t\t\tfor ( const child of this.viewChildrenToDom( viewNode, domDocument, options ) ) {\n\t\t\t\t\tdomElement.appendChild( child );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn domElement;\n\t\t}\n\t}\n\n\t/**\n\t * Converts children of the view element to DOM using the\n\t * {@link module:engine/view/domconverter~DomConverter#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 {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewElement Parent view element.\n\t * @param {Document} domDocument Document which will be used to create DOM nodes.\n\t * @param {Object} options See {@link module:engine/view/domconverter~DomConverter#viewToDom} options parameter.\n\t * @returns {Iterable.<Node>} DOM nodes.\n\t */\n\t* viewChildrenToDom( viewElement, domDocument, options = {} ) {\n\t\tconst fillerPositionOffset = viewElement.getFillerOffset && viewElement.getFillerOffset();\n\t\tlet offset = 0;\n\n\t\tfor ( const childView of viewElement.getChildren() ) {\n\t\t\tif ( fillerPositionOffset === offset ) {\n\t\t\t\tyield this.blockFiller( domDocument );\n\t\t\t}\n\n\t\t\tyield this.viewToDom( childView, domDocument, options );\n\n\t\t\toffset++;\n\t\t}\n\n\t\tif ( fillerPositionOffset === offset ) {\n\t\t\tyield this.blockFiller( domDocument );\n\t\t}\n\t}\n\n\t/**\n\t * Converts view {@link module:engine/view/range~Range} to DOM range.\n\t * Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t *\n\t * @param {module:engine/view/range~Range} viewRange View range.\n\t * @returns {Range} DOM range.\n\t */\n\tviewRangeToDom( viewRange ) {\n\t\tconst domStart = this.viewPositionToDom( viewRange.start );\n\t\tconst domEnd = this.viewPositionToDom( viewRange.end );\n\n\t\tconst domRange = document.createRange();\n\t\tdomRange.setStart( domStart.parent, domStart.offset );\n\t\tdomRange.setEnd( domEnd.parent, domEnd.offset );\n\n\t\treturn domRange;\n\t}\n\n\t/**\n\t * Converts view {@link module:engine/view/position~Position} 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 {module:engine/view/position~Position} viewPosition View position.\n\t * @returns {Object|null} position DOM position or `null` if view position could not be converted to DOM.\n\t * @returns {Node} position.parent DOM position parent.\n\t * @returns {Number} position.offset DOM position offset.\n\t */\n\tviewPositionToDom( viewPosition ) {\n\t\tconst viewParent = viewPosition.parent;\n\n\t\tif ( viewParent.is( 'text' ) ) {\n\t\t\tconst domParent = this.findCorrespondingDomText( viewParent );\n\n\t\t\tif ( !domParent ) {\n\t\t\t\t// Position is in a view text node that has not been rendered to DOM yet.\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tlet offset = viewPosition.offset;\n\n\t\t\tif ( startsWithFiller( domParent ) ) {\n\t\t\t\toffset += INLINE_FILLER_LENGTH;\n\t\t\t}\n\n\t\t\treturn { parent: domParent, offset };\n\t\t} else {\n\t\t\t// viewParent is instance of ViewElement.\n\t\t\tlet domParent, domBefore, domAfter;\n\n\t\t\tif ( viewPosition.offset === 0 ) {\n\t\t\t\tdomParent = this.mapViewToDom( viewParent );\n\n\t\t\t\tif ( !domParent ) {\n\t\t\t\t\t// Position is in a view element that has not been rendered to DOM yet.\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tdomAfter = domParent.childNodes[ 0 ];\n\t\t\t} else {\n\t\t\t\tconst nodeBefore = viewPosition.nodeBefore;\n\n\t\t\t\tdomBefore = nodeBefore.is( 'text' ) ?\n\t\t\t\t\tthis.findCorrespondingDomText( nodeBefore ) :\n\t\t\t\t\tthis.mapViewToDom( viewPosition.nodeBefore );\n\n\t\t\t\tif ( !domBefore ) {\n\t\t\t\t\t// Position is after a view element that has not been rendered to DOM yet.\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tdomParent = domBefore.parentNode;\n\t\t\t\tdomAfter = domBefore.nextSibling;\n\t\t\t}\n\n\t\t\t// If there is an inline filler at position return position inside the filler. We should never return\n\t\t\t// the position before the inline filler.\n\t\t\tif ( this.isText( domAfter ) && startsWithFiller( domAfter ) ) {\n\t\t\t\treturn { parent: domAfter, offset: INLINE_FILLER_LENGTH };\n\t\t\t}\n\n\t\t\tconst offset = domBefore ? indexOf( domBefore ) + 1 : 0;\n\n\t\t\treturn { parent: domParent, offset };\n\t\t}\n\t}\n\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~UIElement} that UIElement will be returned.\n\t *\n\t * @param {Node|DocumentFragment} domNode DOM node or document fragment to transform.\n\t * @param {Object} [options] Conversion options.\n\t * @param {Boolean} [options.bind=false] Determines whether new elements will be bound.\n\t * @param {Boolean} [options.withChildren=true] If `true`, node's and document fragment's children will be converted too.\n\t * @param {Boolean} [options.keepOriginalCase=false] If `false`, node's tag name will be converter to lower case.\n\t * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null} Converted node or document fragment\n\t * or `null` if DOM node is a {@link module:engine/view/filler filler} or the given node is an empty text node.\n\t */\n\tdomToView( domNode, options = {} ) {\n\t\tif ( isBlockFiller( domNode, this.blockFiller ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// When node is inside UIElement return that UIElement as it's view representation.\n\t\tconst uiElement = this.getParentUIElement( domNode, this._domToViewMapping );\n\n\t\tif ( uiElement ) {\n\t\t\treturn uiElement;\n\t\t}\n\n\t\tif ( this.isText( domNode ) ) {\n\t\t\tif ( isInlineFiller( domNode ) ) {\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\tconst textData = this._processDataFromDomText( domNode );\n\n\t\t\t\treturn textData === '' ? null : new ViewText( textData );\n\t\t\t}\n\t\t} else if ( this.isComment( domNode ) ) {\n\t\t\treturn null;\n\t\t} else {\n\t\t\tif ( this.mapDomToView( domNode ) ) {\n\t\t\t\treturn this.mapDomToView( domNode );\n\t\t\t}\n\n\t\t\tlet viewElement;\n\n\t\t\tif ( this.isDocumentFragment( domNode ) ) {\n\t\t\t\t// Create view document fragment.\n\t\t\t\tviewElement = new ViewDocumentFragment();\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindDocumentFragments( domNode, viewElement );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Create view element.\n\t\t\t\tconst viewName = options.keepOriginalCase ? domNode.tagName : domNode.tagName.toLowerCase();\n\t\t\t\tviewElement = new ViewElement( viewName );\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domNode, viewElement );\n\t\t\t\t}\n\n\t\t\t\t// Copy element's attributes.\n\t\t\t\tconst attrs = domNode.attributes;\n\n\t\t\t\tfor ( let i = attrs.length - 1; i >= 0; i-- ) {\n\t\t\t\t\tviewElement.setAttribute( attrs[ i ].name, attrs[ i ].value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( options.withChildren || options.withChildren === undefined ) {\n\t\t\t\tfor ( const child of this.domChildrenToView( domNode, options ) ) {\n\t\t\t\t\tviewElement.appendChildren( child );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn viewElement;\n\t\t}\n\t}\n\n\t/**\n\t * Converts children of the DOM element to view nodes using\n\t * the {@link module:engine/view/domconverter~DomConverter#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 {HTMLElement} domElement Parent DOM element.\n\t * @param {Object} options See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.\n\t * @returns {Iterable.<module:engine/view/node~Node>} View nodes.\n\t */\n\t* domChildrenToView( domElement, options = {} ) {\n\t\tfor ( let i = 0; i < domElement.childNodes.length; i++ ) {\n\t\t\tconst domChild = domElement.childNodes[ i ];\n\t\t\tconst viewChild = this.domToView( domChild, options );\n\n\t\t\tif ( viewChild !== null ) {\n\t\t\t\tyield viewChild;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Converts DOM selection to view {@link module:engine/view/selection~Selection}.\n\t * Ranges which cannot be converted will be omitted.\n\t *\n\t * @param {Selection} domSelection DOM selection.\n\t * @returns {module:engine/view/selection~Selection} View selection.\n\t */\n\tdomSelectionToView( domSelection ) {\n\t\t// DOM selection might be placed in fake selection container.\n\t\t// If container contains fake selection - return corresponding view selection.\n\t\tif ( domSelection.rangeCount === 1 ) {\n\t\t\tlet container = domSelection.getRangeAt( 0 ).startContainer;\n\n\t\t\t// The DOM selection might be moved to the text node inside the fake selection container.\n\t\t\tif ( this.isText( container ) ) {\n\t\t\t\tcontainer = container.parentNode;\n\t\t\t}\n\n\t\t\tconst viewSelection = this.fakeSelectionToView( container );\n\n\t\t\tif ( viewSelection ) {\n\t\t\t\treturn viewSelection;\n\t\t\t}\n\t\t}\n\n\t\tconst viewSelection = new ViewSelection();\n\t\tconst isBackward = this.isDomSelectionBackward( domSelection );\n\n\t\tfor ( let i = 0; i < domSelection.rangeCount; i++ ) {\n\t\t\t// DOM Range have correct start and end, no matter what is the DOM Selection direction. So we don't have to fix anything.\n\t\t\tconst domRange = domSelection.getRangeAt( i );\n\t\t\tconst viewRange = this.domRangeToView( domRange );\n\n\t\t\tif ( viewRange ) {\n\t\t\t\tviewSelection.addRange( viewRange, isBackward );\n\t\t\t}\n\t\t}\n\n\t\treturn viewSelection;\n\t}\n\n\t/**\n\t * Converts DOM Range to view {@link module:engine/view/range~Range}.\n\t * If the start or end position can not be converted `null` is returned.\n\t *\n\t * @param {Range} domRange DOM range.\n\t * @returns {module:engine/view/range~Range|null} 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\n\t\tif ( viewStart && viewEnd ) {\n\t\t\treturn new ViewRange( viewStart, viewEnd );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Converts DOM parent and offset to view {@link module:engine/view/position~Position}.\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~UIElement}\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 {Node} domParent DOM position parent.\n\t * @param {Number} domOffset DOM position offset.\n\t * @returns {module:engine/view/position~Position} viewPosition View position.\n\t */\n\tdomPositionToView( domParent, domOffset ) {\n\t\tif ( isBlockFiller( domParent, this.blockFiller ) ) {\n\t\t\treturn this.domPositionToView( domParent.parentNode, indexOf( domParent ) );\n\t\t}\n\n\t\t// If position is somewhere inside UIElement - return position before that element.\n\t\tconst viewElement = this.mapDomToView( domParent );\n\n\t\tif ( viewElement && viewElement.is( 'uiElement' ) ) {\n\t\t\treturn ViewPosition.createBefore( viewElement );\n\t\t}\n\n\t\tif ( this.isText( domParent ) ) {\n\t\t\tif ( isInlineFiller( domParent ) ) {\n\t\t\t\treturn this.domPositionToView( domParent.parentNode, indexOf( domParent ) );\n\t\t\t}\n\n\t\t\tconst viewParent = this.findCorrespondingViewText( domParent );\n\t\t\tlet offset = domOffset;\n\n\t\t\tif ( !viewParent ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( startsWithFiller( domParent ) ) {\n\t\t\t\toffset -= INLINE_FILLER_LENGTH;\n\t\t\t\toffset = offset < 0 ? 0 : offset;\n\t\t\t}\n\n\t\t\treturn new ViewPosition( viewParent, offset );\n\t\t}\n\t\t// domParent instanceof HTMLElement.\n\t\telse {\n\t\t\tif ( domOffset === 0 ) {\n\t\t\t\tconst viewParent = this.mapDomToView( domParent );\n\n\t\t\t\tif ( viewParent ) {\n\t\t\t\t\treturn new ViewPosition( viewParent, 0 );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst domBefore = domParent.childNodes[ domOffset - 1 ];\n\t\t\t\tconst viewBefore = this.isText( domBefore ) ?\n\t\t\t\t\tthis.findCorrespondingViewText( domBefore ) :\n\t\t\t\t\tthis.mapDomToView( domBefore );\n\n\t\t\t\t// TODO #663\n\t\t\t\tif ( viewBefore && viewBefore.parent ) {\n\t\t\t\t\treturn new ViewPosition( viewBefore.parent, viewBefore.index + 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Returns corresponding view {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment} for provided DOM element or\n\t * document fragment. If there is no view item {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * to the given DOM - `undefined` is returned.\n\t * For all DOM elements rendered by {@link module:engine/view/uielement~UIElement} that UIElement will be returned.\n\t *\n\t * @param {DocumentFragment|Element} domElementOrDocumentFragment DOM element or document fragment.\n\t * @returns {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|undefined}\n\t * Corresponding view element, document fragment or `undefined` if no element was bound.\n\t */\n\tmapDomToView( domElementOrDocumentFragment ) {\n\t\treturn this.getParentUIElement( domElementOrDocumentFragment ) || this._domToViewMapping.get( domElementOrDocumentFragment );\n\t}\n\n\t/**\n\t * Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~DomConverter#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~DomConverter#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 {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * element, it is used to find the corresponding text node.\n\t *\n\t * For all text nodes rendered by {@link module:engine/view/uielement~UIElement} that UIElement 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 {Text} domText DOM text node.\n\t * @returns {module:engine/view/text~Text|null} Corresponding view text node or `null`, if it was not possible to find a\n\t * corresponding node.\n\t */\n\tfindCorrespondingViewText( domText ) {\n\t\tif ( isInlineFiller( domText ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// If DOM text was rendered by UIElement - return that element.\n\t\tconst uiElement = this.getParentUIElement( domText );\n\n\t\tif ( uiElement ) {\n\t\t\treturn uiElement;\n\t\t}\n\n\t\tconst previousSibling = domText.previousSibling;\n\n\t\t// Try to use previous sibling to find the corresponding text node.\n\t\tif ( previousSibling ) {\n\t\t\tif ( !( this.isElement( previousSibling ) ) ) {\n\t\t\t\t// The previous is text or comment.\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst viewElement = this.mapDomToView( previousSibling );\n\n\t\t\tif ( viewElement ) {\n\t\t\t\tconst nextSibling = viewElement.nextSibling;\n\n\t\t\t\t// It might be filler which has no corresponding view node.\n\t\t\t\tif ( nextSibling instanceof ViewText ) {\n\t\t\t\t\treturn viewElement.nextSibling;\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Try to use parent to find the corresponding text node.\n\t\telse {\n\t\t\tconst viewElement = this.mapDomToView( domText.parentNode );\n\n\t\t\tif ( viewElement ) {\n\t\t\t\tconst firstChild = viewElement.getChild( 0 );\n\n\t\t\t\t// It might be filler which has no corresponding view node.\n\t\t\t\tif ( firstChild instanceof ViewText ) {\n\t\t\t\t\treturn firstChild;\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns corresponding DOM item for provided {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment}.\n\t * To find a corresponding text for {@link module:engine/view/text~Text view Text instance}\n\t * use {@link #findCorrespondingDomText}.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewNode\n\t * View element or document fragment.\n\t * @returns {Node|DocumentFragment|undefined} Corresponding DOM node or document fragment.\n\t */\n\tmapViewToDom( documentFragmentOrElement ) {\n\t\treturn this._viewToDomMapping.get( documentFragmentOrElement );\n\t}\n\n\t/**\n\t * Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~DomConverter#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~DomConverter#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 {@link module:engine/view/domconverter~DomConverter#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 {module:engine/view/text~Text} viewText View text node.\n\t * @returns {Text|null} 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\n\t\t// Try to use previous sibling to find the corresponding text node.\n\t\tif ( previousSibling && this.mapViewToDom( previousSibling ) ) {\n\t\t\treturn this.mapViewToDom( previousSibling ).nextSibling;\n\t\t}\n\n\t\t// If this is a first node, try to use parent to find the corresponding text node.\n\t\tif ( !previousSibling && viewText.parent && this.mapViewToDom( viewText.parent ) ) {\n\t\t\treturn this.mapViewToDom( viewText.parent ).childNodes[ 0 ];\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Focuses DOM editable that is corresponding to provided {@link module:engine/view/editableelement~EditableElement}.\n\t *\n\t * @param {module:engine/view/editableelement~EditableElement} viewEditable\n\t */\n\tfocus( viewEditable ) {\n\t\tconst domEditable = this.mapViewToDom( viewEditable );\n\n\t\tif ( domEditable && domEditable.ownerDocument.activeElement !== domEditable ) {\n\t\t\t// Save the scrollX and scrollY positions before the focus.\n\t\t\tconst { scrollX, scrollY } = global.window;\n\t\t\tconst scrollPositions = [];\n\n\t\t\t// Save all scrollLeft and scrollTop values starting from domEditable up to\n\t\t\t// document#documentElement.\n\t\t\tforEachDomNodeAncestor( domEditable, node => {\n\t\t\t\tconst { scrollLeft, scrollTop } = node;\n\n\t\t\t\tscrollPositions.push( [ scrollLeft, scrollTop ] );\n\t\t\t} );\n\n\t\t\tdomEditable.focus();\n\n\t\t\t// Restore scrollLeft and scrollTop values starting from domEditable up to\n\t\t\t// document#documentElement.\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/951\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/957\n\t\t\tforEachDomNodeAncestor( domEditable, node => {\n\t\t\t\tconst [ scrollLeft, scrollTop ] = scrollPositions.shift();\n\n\t\t\t\tnode.scrollLeft = scrollLeft;\n\t\t\t\tnode.scrollTop = scrollTop;\n\t\t\t} );\n\n\t\t\t// Restore the scrollX and scrollY positions after the focus.\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/951\n\t\t\tglobal.window.scrollTo( scrollX, scrollY );\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.TEXT_NODE`.\n\t *\n\t * @param {Node} node Node to check.\n\t * @returns {Boolean}\n\t */\n\tisText( node ) {\n\t\treturn node && node.nodeType == Node.TEXT_NODE;\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.ELEMENT_NODE`.\n\t *\n\t * @param {Node} node Node to check.\n\t * @returns {Boolean}\n\t */\n\tisElement( node ) {\n\t\treturn node && node.nodeType == Node.ELEMENT_NODE;\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.DOCUMENT_FRAGMENT_NODE`.\n\t *\n\t * @param {Node} node Node to check.\n\t * @returns {Boolean}\n\t */\n\tisDocumentFragment( node ) {\n\t\treturn node && node.nodeType == Node.DOCUMENT_FRAGMENT_NODE;\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.COMMENT_NODE`.\n\t *\n\t * @param {Node} node Node to check.\n\t * @returns {Boolean}\n\t */\n\tisComment( node ) {\n\t\treturn node && node.nodeType == Node.COMMENT_NODE;\n\t}\n\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} DOM Selection instance to check.\n\t * @returns {Boolean}\n\t */\n\tisDomSelectionBackward( selection ) {\n\t\tif ( selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Since it takes multiple lines of code to check whether a \"DOM Position\" is before/after another \"DOM Position\",\n\t\t// we will use the fact that range will collapse if it's end is before it's start.\n\t\tconst range = document.createRange();\n\n\t\trange.setStart( selection.anchorNode, selection.anchorOffset );\n\t\trange.setEnd( selection.focusNode, selection.focusOffset );\n\n\t\tconst backward = range.collapsed;\n\n\t\trange.detach();\n\n\t\treturn backward;\n\t}\n\n\t/**\n\t * Returns parent {@link module:engine/view/uielement~UIElement} for provided DOM node. Returns `null` if there is no\n\t * parent UIElement.\n\t *\n\t * @param {Node} domNode\n\t * @return {module:engine/view/uielement~UIElement|null}\n\t */\n\tgetParentUIElement( domNode ) {\n\t\tconst ancestors = getAncestors( domNode );\n\n\t\t// Remove domNode from the list.\n\t\tancestors.pop();\n\n\t\twhile ( ancestors.length ) {\n\t\t\tconst domNode = ancestors.pop();\n\t\t\tconst viewNode = this._domToViewMapping.get( domNode );\n\n\t\t\tif ( viewNode && viewNode.is( 'uiElement' ) ) {\n\t\t\t\treturn viewNode;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks if given selection's boundaries are at correct places.\n\t *\n\t * The following places are considered as incorrect for selection boundaries:\n\t * * before or in the middle of the inline filler sequence,\n\t * * inside the DOM element which represents {@link module:engine/view/uielement~UIElement a view ui element}.\n\t *\n\t * @param {Selection} domSelection DOM Selection object to be checked.\n\t * @returns {Boolean} `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 ) &&\n\t\t\tthis._isDomSelectionPositionCorrect( domSelection.focusNode, domSelection.focusOffset );\n\t}\n\n\t/**\n\t * Checks if the given DOM position is a correct place for selection boundary. See {@link #isDomSelectionCorrect}.\n\t *\n\t * @private\n\t * @param {Element} domParent Position parent.\n\t * @param {Number} offset Position offset.\n\t * @returns {Boolean} `true` if given position is at a correct place for selection boundary, `false` otherwise.\n\t */\n\t_isDomSelectionPositionCorrect( domParent, offset ) {\n\t\t// If selection is before or in the middle of inline filler string, it is incorrect.\n\t\tif ( this.isText( domParent ) && startsWithFiller( domParent ) && offset < INLINE_FILLER_LENGTH ) {\n\t\t\t// Selection in a text node, at wrong position (before or in the middle of filler).\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.isElement( domParent ) && startsWithFiller( domParent.childNodes[ offset ] ) ) {\n\t\t\t// Selection in an element node, before filler text node.\n\t\t\treturn false;\n\t\t}\n\n\t\tconst viewParent = this.mapDomToView( domParent );\n\n\t\t// If selection is in `view.UIElement`, it is incorrect. Note that `mapDomToView()` returns `view.UIElement`\n\t\t// also for any dom element that is inside the view ui element (so we don't need to perform any additional checks).\n\t\tif ( viewParent && viewParent.is( 'uiElement' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Takes text data from a given {@link module:engine/view/text~Text#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 this 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 * @private\n\t * @param {module:engine/view/text~Text} node View text node to process.\n\t * @returns {String} Processed text data.\n\t */\n\t_processDataFromViewText( node ) {\n\t\tlet data = node.data;\n\n\t\t// If any of node ancestors has a name which is in `preElements` array, then currently processed\n\t\t// view text node is (will be) in preformatted element. We should not change whitespaces then.\n\t\tif ( node.getAncestors().some( parent => this.preElements.includes( parent.name ) ) ) {\n\t\t\treturn data;\n\t\t}\n\n\t\t// 1. Replace the first space with a nbsp if the previous node ends with a space or there is no previous node\n\t\t// (container element boundary).\n\t\tif ( data.charAt( 0 ) == ' ' ) {\n\t\t\tconst prevNode = this._getTouchingViewTextNode( node, false );\n\t\t\tconst prevEndsWithSpace = prevNode && this._nodeEndsWithSpace( prevNode );\n\n\t\t\tif ( prevEndsWithSpace || !prevNode ) {\n\t\t\t\tdata = '\\u00A0' + data.substr( 1 );\n\t\t\t}\n\t\t}\n\n\t\t// 2. Replace the last space with a nbsp if this is the last text node (container element boundary).\n\t\tif ( data.charAt( data.length - 1 ) == ' ' ) {\n\t\t\tconst nextNode = this._getTouchingViewTextNode( node, true );\n\n\t\t\tif ( !nextNode ) {\n\t\t\t\tdata = data.substr( 0, data.length - 1 ) + '\\u00A0';\n\t\t\t}\n\t\t}\n\n\t\treturn data.replace( / {2}/g, ' \\u00A0' );\n\t}\n\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 * @private\n\t * @param {module:engine/view/text~Text} node Node to check.\n\t * @returns {Boolean} `true` if given `node` ends with space, `false` otherwise.\n\t */\n\t_nodeEndsWithSpace( node ) {\n\t\tif ( node.getAncestors().some( parent => this.preElements.includes( parent.name ) ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst data = this._processDataFromViewText( node );\n\n\t\treturn data.charAt( data.length - 1 ) == ' ';\n\t}\n\n\t/**\n\t * Takes text data from native `Text` node and processes it to a correct {@link module:engine/view/text~Text view text node} data.\n\t *\n\t * Following changes are done:\n\t * * multiple whitespaces are replaced to a single space,\n\t * * space at the beginning of the text node is removed, if it is a first text node in it's container\n\t * element or if previous text node ends by space character,\n\t * * space at the end of the text node is removed, if it is a last text node in it's container.\n\t *\n\t * @param {Node} node DOM text node to process.\n\t * @returns {String} Processed data.\n\t * @private\n\t */\n\t_processDataFromDomText( node ) {\n\t\tlet data = getDataWithoutFiller( node );\n\n\t\tif ( _hasDomParentOfType( node, this.preElements ) ) {\n\t\t\treturn data;\n\t\t}\n\n\t\t// Change all consecutive whitespace characters (from the [ \\n\\t\\r] set \n\t\t// see https://github.com/ckeditor/ckeditor5-engine/issues/822#issuecomment-311670249) to a single space character.\n\t\t// That's how multiple whitespaces are treated when rendered, so we normalize those whitespaces.\n\t\t// We're replacing 1+ (and not 2+) to also normalize singular \\n\\t\\r characters (#822).\n\t\tdata = data.replace( /[ \\n\\t\\r]{1,}/g, ' ' );\n\n\t\tconst prevNode = this._getTouchingDomTextNode( node, false );\n\t\tconst nextNode = this._getTouchingDomTextNode( node, true );\n\n\t\t// If previous dom text node does not exist or it ends by whitespace character, remove space character from the beginning\n\t\t// of this text node. Such space character is treated as a whitespace.\n\t\tif ( !prevNode || /[^\\S\\u00A0]/.test( prevNode.data.charAt( prevNode.data.length - 1 ) ) ) {\n\t\t\tdata = data.replace( /^ /, '' );\n\t\t}\n\n\t\t// If next text node does not exist remove space character from the end of this text node.\n\t\tif ( !nextNode ) {\n\t\t\tdata = data.replace( / $/, '' );\n\t\t}\n\t\t// At this point we should have removed all whitespaces from DOM text data.\n\n\t\t// Now we have to change &nbsp; chars, that were in DOM text data because of rendering reasons, to spaces.\n\t\t// First, change all ` \\u00A0` pairs (space + &nbsp;) to two spaces. DOM converter changes two spaces from model/view as\n\t\t// ` \\u00A0` to ensure proper rendering. Since here we convert back, we recognize those pairs and change them\n\t\t// to ` ` which is what we expect to have in model/view.\n\t\tdata = data.replace( / \\u00A0/g, ' ' );\n\n\t\t// Then, change &nbsp; character that is at the beginning of the text node to space character.\n\t\t// As above, that &nbsp; was created for rendering reasons but it's real meaning is just a space character.\n\t\t// We do that replacement only if this is the first node or the previous node ends on whitespace character.\n\t\tif ( !prevNode || /[^\\S\\u00A0]/.test( prevNode.data.charAt( prevNode.data.length - 1 ) ) ) {\n\t\t\tdata = data.replace( /^\\u00A0/, ' ' );\n\t\t}\n\n\t\t// Since input text data could be: `x_ _`, we would not replace the first &nbsp; after `x` character.\n\t\t// We have to fix it. Since we already change all ` &nbsp;`, we will have something like this at the end of text data:\n\t\t// `x_ _ _` -> `x_ `. Find &nbsp; at the end of string (can be followed only by spaces).\n\t\t// We do that replacement only if this is the last node or the next node starts by &nbsp;.\n\t\tif ( !nextNode || nextNode.data.charAt( 0 ) == '\\u00A0' ) {\n\t\t\tdata = data.replace( /\\u00A0( *)$/, ' $1' );\n\t\t}\n\n\t\t// At this point, all whitespaces should be removed and all &nbsp; created for rendering reasons should be\n\t\t// changed to normal space. All left &nbsp; are &nbsp; inserted intentionally.\n\t\treturn data;\n\t}\n\n\t/**\n\t * Helper function. For given {@link module:engine/view/text~Text 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 {module:engine/view/text~Text} node Reference node.\n\t * @param {Boolean} getNext\n\t * @returns {module:engine/view/text~Text|null} Touching text node or `null` if there is no next or previous touching text node.\n\t */\n\t_getTouchingViewTextNode( 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\n\t\tfor ( const value of treeWalker ) {\n\t\t\tif ( value.item.is( 'containerElement' ) ) {\n\t\t\t\t// ViewContainerElement is found on a way to next ViewText node, so given `node` was first/last\n\t\t\t\t// text node in its container element.\n\t\t\t\treturn null;\n\t\t\t} else if ( value.item.is( 'text' ) ) {\n\t\t\t\t// Found a text node in the same container element.\n\t\t\t\treturn value.item;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Helper function. For given `Text` node, it finds previous or next sibling that is contained in the same block element.\n\t * If there is no such sibling, `null` is returned.\n\t *\n\t * @private\n\t * @param {Text} node\n\t * @param {Boolean} getNext\n\t * @returns {Text|null}\n\t */\n\t_getTouchingDomTextNode( node, getNext ) {\n\t\tif ( !node.parentNode ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst direction = getNext ? 'nextNode' : 'previousNode';\n\t\tconst document = node.ownerDocument;\n\t\tconst treeWalker = document.createTreeWalker( document.childNodes[ 0 ], NodeFilter.SHOW_TEXT );\n\n\t\ttreeWalker.currentNode = node;\n\n\t\tconst touchingNode = treeWalker[ direction ]();\n\n\t\tif ( touchingNode !== null ) {\n\t\t\tconst lca = getCommonAncestor( node, touchingNode );\n\n\t\t\t// If there is common ancestor between the text node and next/prev text node,\n\t\t\t// and there are no block elements on a way from the text node to that ancestor,\n\t\t\t// and there are no block elements on a way from next/prev text node to that ancestor...\n\t\t\tif (\n\t\t\t\tlca &&\n\t\t\t\t!_hasDomParentOfType( node, this.blockElements, lca ) &&\n\t\t\t\t!_hasDomParentOfType( touchingNode, this.blockElements, lca )\n\t\t\t) {\n\t\t\t\t// Then they are in the same container element.\n\t\t\t\treturn touchingNode;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\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// @param {Node} node\n// @param {Array.<String>} types\n// @param {Boolean} [boundaryParent] Can be given if parents should be checked up to a given element (excluding that element).\n// @returns {Boolean} `true` if such parent exists or `false` if it does not.\nfunction _hasDomParentOfType( node, types, boundaryParent ) {\n\tlet parents = getAncestors( node );\n\n\tif ( boundaryParent ) {\n\t\tparents = parents.slice( parents.indexOf( boundaryParent ) + 1 );\n\t}\n\n\treturn parents.some( parent => parent.tagName && types.includes( parent.tagName.toLowerCase() ) );\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 {Node} node\n// @param {Function} callback A callback to be executed for each ancestor.\nfunction forEachDomNodeAncestor( node, callback ) {\n\twhile ( node && node != global.document ) {\n\t\tcallback( node );\n\t\tnode = node.parentNode;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/domconverter.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/rooteditableelement\n */\n\nimport EditableElement from './editableelement';\n\nconst rootNameSymbol = Symbol( 'rootName' );\n\n/**\n * Class representing a single root in the data view. A root can be either {@link #isReadOnly editable or read-only}, but\n * in both cases it is called \"an editable\". Roots can contain other {@link module:engine/view/editableelement~EditableElement editable\n * elements}\n * making them \"nested editables\".\n *\n * @extends module:engine/view/editableelement~EditableElement\n */\nexport default class RootEditableElement extends EditableElement {\n\t/**\n\t * Creates root editable element.\n\t *\n\t * @param {module:engine/view/document~Document} document {@link module:engine/view/document~Document} that is an owner of the root.\n\t * @param {String} name Node name.\n\t */\n\tconstructor( name ) {\n\t\tsuper( name );\n\n\t\t/**\n\t\t * Name of this root inside {@link module:engine/view/document~Document} that is an owner of this root. If no\n\t\t * other name is set, `main` name is used.\n\t\t *\n\t\t * @member {String}\n\t\t */\n\t\tthis.rootName = 'main';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'rootElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'rootElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\tget rootName() {\n\t\treturn this.getCustomProperty( rootNameSymbol );\n\t}\n\n\tset rootName( rootName ) {\n\t\tthis.setCustomProperty( rootNameSymbol, rootName );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/rooteditableelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/fakeselectionobserver\n */\n\nimport Observer from './observer';\nimport ViewSelection from '../selection';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport debounce from '@ckeditor/ckeditor5-utils/src/lib/lodash/debounce';\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~Document#event:keydown keydown} events and handles moving fake view selection to the correct place\n * if arrow keys are pressed.\n * Fires {@link module:engine/view/document~Document#event:selectionChange selectionChange event} simulating natural behaviour of\n * {@link module:engine/view/observer/selectionobserver~SelectionObserver SelectionObserver}.\n *\n * @extends module:engine/view/observer/observer~Observer.Observer\n */\nexport default class FakeSelectionObserver extends Observer {\n\t/**\n\t * Creates new FakeSelectionObserver instance.\n\t *\n\t * @param {module:engine/view/document~Document} document\n\t */\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\t/**\n\t\t * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.\n\t\t *\n\t\t * @private\n\t\t * @param {Object} data Selection change data.\n\t\t * @method #_fireSelectionChangeDoneDebounced\n\t\t */\n\t\tthis._fireSelectionChangeDoneDebounced = debounce( data => this.document.fire( 'selectionChangeDone', data ), 200 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve() {\n\t\tconst document = this.document;\n\n\t\tdocument.on( 'keydown', ( eventInfo, data ) => {\n\t\t\tconst selection = document.selection;\n\n\t\t\tif ( selection.isFake && _isArrowKeyCode( data.keyCode ) && this.isEnabled ) {\n\t\t\t\t// Prevents default key down handling - no selection change will occur.\n\t\t\t\tdata.preventDefault();\n\n\t\t\t\tthis._handleSelectionMove( data.keyCode );\n\t\t\t}\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tthis._fireSelectionChangeDoneDebounced.cancel();\n\t}\n\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~Document#event:selectionChange} and\n\t * {@link module:engine/view/document~Document#event:selectionChangeDone} events imitating behaviour of\n\t * {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n\t *\n\t * @private\n\t * @param {Number} keyCode\n\t * @fires module:engine/view/document~Document#event:selectionChange\n\t * @fires module:engine/view/document~Document#event:selectionChangeDone\n\t */\n\t_handleSelectionMove( keyCode ) {\n\t\tconst selection = this.document.selection;\n\t\tconst newSelection = ViewSelection.createFromSelection( selection );\n\t\tnewSelection.setFake( false );\n\n\t\t// Left or up arrow pressed - move selection to start.\n\t\tif ( keyCode == keyCodes.arrowleft || keyCode == keyCodes.arrowup ) {\n\t\t\tnewSelection.collapseToStart();\n\t\t}\n\n\t\t// Right or down arrow pressed - move selection to end.\n\t\tif ( keyCode == keyCodes.arrowright || keyCode == keyCodes.arrowdown ) {\n\t\t\tnewSelection.collapseToEnd();\n\t\t}\n\n\t\tconst data = {\n\t\t\toldSelection: selection,\n\t\t\tnewSelection,\n\t\t\tdomSelection: null\n\t\t};\n\n\t\t// Fire dummy selection change event.\n\t\tthis.document.fire( 'selectionChange', data );\n\n\t\t// Call` #_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.\n\t\t// This function is debounced what means that `selectionChangeDone` event will be fired only when\n\t\t// defined int the function time will elapse since the last time the function was called.\n\t\t// So `selectionChangeDone` will be fired when selection will stop changing.\n\t\tthis._fireSelectionChangeDoneDebounced( data );\n\t}\n}\n\n// Checks if one of the arrow keys is pressed.\n//\n// @private\n// @param {Number} keyCode\n// @returns {Boolean}\nfunction _isArrowKeyCode( keyCode ) {\n\treturn keyCode == keyCodes.arrowright ||\n\t\tkeyCode == keyCodes.arrowleft ||\n\t\tkeyCode == keyCodes.arrowup ||\n\t\tkeyCode == keyCodes.arrowdown;\n}\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/fakeselectionobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/isrange\n */\n\n/**\n * Checks if the object is a native DOM Range.\n *\n * @param {*} obj\n * @returns {Boolean}\n */\nexport default function isRange( obj ) {\n\treturn Object.prototype.toString.apply( obj ) == '[object Range]';\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/isrange.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/iswindow\n */\n\n/**\n * Checks if the object is a native DOM Window.\n *\n * @param {*} obj\n * @returns {Boolean}\n */\nexport default function isWindow( obj ) {\n\treturn Object.prototype.toString.apply( obj ) == '[object Window]';\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/iswindow.js\n// module id = null\n// module chunks = ","import isObjectLike from './isObjectLike';\nimport isPlainObject from './isPlainObject';\n\n/**\n * Checks if `value` is likely a DOM element.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a DOM element,\n * else `false`.\n * @example\n *\n * _.isElement(document.body);\n * // => true\n *\n * _.isElement('<body>');\n * // => false\n */\nfunction isElement(value) {\n return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);\n}\n\nexport default isElement;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isElement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/getborderwidths\n */\n\n/**\n * Returns an object containing CSS border widths of a specified HTML element.\n *\n * @param {HTMLElement} element An element which has CSS borders.\n * @param {Object} An object containing `top`, `left`, `right` and `bottom` properties\n * with numerical values of the `border-[top,left,right,bottom]-width` CSS styles.\n */\nexport default function getBorderWidths( element ) {\n\t// Call getComputedStyle on the window the element document belongs to.\n\tconst style = element.ownerDocument.defaultView.getComputedStyle( element );\n\n\treturn {\n\t\ttop: parseInt( style.borderTopWidth, 10 ),\n\t\tright: parseInt( style.borderRightWidth, 10 ),\n\t\tbottom: parseInt( style.borderBottomWidth, 10 ),\n\t\tleft: parseInt( style.borderLeftWidth, 10 )\n\t};\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/getborderwidths.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/rect\n */\n\nimport isRange from './isrange';\nimport isWindow from './iswindow';\nimport isElement from '../lib/lodash/isElement';\nimport getBorderWidths from './getborderwidths';\nimport log from '../log';\n\n/**\n * A helper class representing a `ClientRect` object, e.g. value returned by\n * the native `object.getBoundingClientRect()` method. Provides a set of methods\n * to manipulate the rect and compare it against other rect instances.\n */\nexport default class Rect {\n\t/**\n\t * Creates an instance of rect.\n\t *\n\t *\t\t// Rect of an HTMLElement.\n\t *\t\tconst rectA = new Rect( document.body );\n\t *\n\t *\t\t// Rect of a DOM Range.\n\t *\t\tconst rectB = new Rect( document.getSelection().getRangeAt( 0 ) );\n\t *\n\t *\t\t// Rect of a window (web browser viewport).\n\t *\t\tconst rectC = new Rect( window );\n\t *\n\t *\t\t// Rect out of an object.\n\t *\t\tconst rectD = new Rect( { top: 0, right: 10, bottom: 10, left: 0, width: 10, height: 10 } );\n\t *\n\t *\t\t// Rect out of another Rect instance.\n\t *\t\tconst rectE = new Rect( rectD );\n\t *\n\t *\t\t// Rect out of a ClientRect.\n\t *\t\tconst rectF = new Rect( document.body.getClientRects().item( 0 ) );\n\t *\n\t * **Note**: By default a rect of an HTML element includes its CSS borders and scrollbars (if any)\n\t * ant the rect of a `window` includes scrollbars too. Use {@link #excludeScrollbarsAndBorders}\n\t * to get the inner part of the rect.\n\t *\n\t * @param {HTMLElement|Range|Window|ClientRect|module:utils/dom/rect~Rect|Object} source A source object to create the rect.\n\t */\n\tconstructor( source ) {\n\t\tconst isSourceRange = isRange( source );\n\n\t\t/**\n\t\t * The object this rect is for.\n\t\t *\n\t\t * @protected\n\t\t * @readonly\n\t\t * @member {HTMLElement|Range|ClientRect|module:utils/dom/rect~Rect|Object} #_source\n\t\t */\n\t\tObject.defineProperty( this, '_source', {\n\t\t\t// If the source is a Rect instance, copy it's #_source.\n\t\t\tvalue: source._source || source,\n\t\t\twritable: true,\n\t\t\tenumerable: false\n\t\t} );\n\n\t\tif ( isElement( source ) || isSourceRange ) {\n\t\t\tconst sourceNode = isSourceRange ? source.startContainer : source;\n\n\t\t\tif ( !sourceNode.ownerDocument || !sourceNode.ownerDocument.body.contains( sourceNode ) ) {\n\t\t\t\t/**\n\t\t\t\t * The `Rect` class depends on `getBoundingClientRect` and `getClientRects` DOM methods.\n\t\t\t\t * If the {@link #constructor source} of a rect in an HTML element or a DOM range but it does\n\t\t\t\t * not belong to any rendered DOM tree, these methods will fail to obtain the geometry and\n\t\t\t\t * the rect instance makes little sense to the features using it.\n\t\t\t\t *\n\t\t\t\t * To get rid of this warning make sure the source passed to the constructor\n\t\t\t\t * is a descendant of `window.document.body`.\n\t\t\t\t *\n\t\t\t\t * @error rect-source-not-in-dom\n\t\t\t\t * @param {String} source The source of the Rect instance.\n\t\t\t\t */\n\t\t\t\tlog.warn(\n\t\t\t\t\t'rect-source-not-in-dom: The source of this rect does not belong to any rendered DOM tree.',\n\t\t\t\t\t{ source }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( isSourceRange ) {\n\t\t\t\tcopyRectProperties( this, Rect.getDomRangeRects( source )[ 0 ] );\n\t\t\t} else {\n\t\t\t\tcopyRectProperties( this, source.getBoundingClientRect() );\n\t\t\t}\n\t\t} else if ( isWindow( source ) ) {\n\t\t\tconst { innerWidth, innerHeight } = source;\n\n\t\t\tcopyRectProperties( this, {\n\t\t\t\ttop: 0,\n\t\t\t\tright: innerWidth,\n\t\t\t\tbottom: innerHeight,\n\t\t\t\tleft: 0,\n\t\t\t\twidth: innerWidth,\n\t\t\t\theight: innerHeight\n\t\t\t} );\n\t\t} else {\n\t\t\tcopyRectProperties( this, source );\n\t\t}\n\n\t\t/**\n\t\t * The \"top\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #top\n\t\t */\n\n\t\t/**\n\t\t * The \"right\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #right\n\t\t */\n\n\t\t/**\n\t\t * The \"bottom\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #bottom\n\t\t */\n\n\t\t/**\n\t\t * The \"left\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #left\n\t\t */\n\n\t\t/**\n\t\t * The \"width\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #width\n\t\t */\n\n\t\t/**\n\t\t * The \"height\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #height\n\t\t */\n\t}\n\n\t/**\n\t * Returns a clone of the rect.\n\t *\n\t * @returns {module:utils/dom/rect~Rect} A cloned rect.\n\t */\n\tclone() {\n\t\treturn new Rect( this );\n\t}\n\n\t/**\n\t * Moves the rect so that its upperleft corner lands in desired `[ x, y ]` location.\n\t *\n\t * @param {Number} x Desired horizontal location.\n\t * @param {Number} y Desired vertical location.\n\t * @returns {module:utils/dom/rect~Rect} A rect which has been moved.\n\t */\n\tmoveTo( x, y ) {\n\t\tthis.top = y;\n\t\tthis.right = x + this.width;\n\t\tthis.bottom = y + this.height;\n\t\tthis.left = x;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Moves the rect inplace by a dedicated offset.\n\t *\n\t * @param {Number} x A horizontal offset.\n\t * @param {Number} y A vertical offset\n\t * @returns {module:utils/dom/rect~Rect} A rect which has been moved.\n\t */\n\tmoveBy( x, y ) {\n\t\tthis.top += y;\n\t\tthis.right += x;\n\t\tthis.left += x;\n\t\tthis.bottom += y;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns a new rect a a result of intersection with another rect.\n\t *\n\t * @param {module:utils/dom/rect~Rect} anotherRect\n\t * @returns {module:utils/dom/rect~Rect}\n\t */\n\tgetIntersection( anotherRect ) {\n\t\tconst rect = {\n\t\t\ttop: Math.max( this.top, anotherRect.top ),\n\t\t\tright: Math.min( this.right, anotherRect.right ),\n\t\t\tbottom: Math.min( this.bottom, anotherRect.bottom ),\n\t\t\tleft: Math.max( this.left, anotherRect.left )\n\t\t};\n\n\t\trect.width = rect.right - rect.left;\n\t\trect.height = rect.bottom - rect.top;\n\n\t\tif ( rect.width < 0 || rect.height < 0 ) {\n\t\t\treturn null;\n\t\t} else {\n\t\t\treturn new Rect( rect );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the area of intersection with another rect.\n\t *\n\t * @param {module:utils/dom/rect~Rect} anotherRect [description]\n\t * @returns {Number} Area of intersection.\n\t */\n\tgetIntersectionArea( anotherRect ) {\n\t\tconst rect = this.getIntersection( anotherRect );\n\n\t\tif ( rect ) {\n\t\t\treturn rect.getArea();\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the area of the rect.\n\t *\n\t * @returns {Number}\n\t */\n\tgetArea() {\n\t\treturn this.width * this.height;\n\t}\n\n\t/**\n\t * Returns a new rect, a part of the original rect, which is actually visible to the user,\n\t * e.g. an original rect cropped by parent element rects which have `overflow` set in CSS\n\t * other than `\"visible\"`.\n\t *\n\t * If there's no such visible rect, which is when the rect is limited by one or many of\n\t * the ancestors, `null` is returned.\n\t *\n\t * @returns {module:utils/dom/rect~Rect|null} A visible rect instance or `null`, if there's none.\n\t */\n\tgetVisible() {\n\t\tconst source = this._source;\n\t\tlet visibleRect = this.clone();\n\n\t\t// There's no ancestor to crop <body> with the overflow.\n\t\tif ( !isBody( source ) ) {\n\t\t\tlet parent = source.parentNode || source.commonAncestorContainer;\n\n\t\t\t// Check the ancestors all the way up to the <body>.\n\t\t\twhile ( parent && !isBody( parent ) ) {\n\t\t\t\tconst parentRect = new Rect( parent );\n\t\t\t\tconst intersectionRect = visibleRect.getIntersection( parentRect );\n\n\t\t\t\tif ( intersectionRect ) {\n\t\t\t\t\tif ( intersectionRect.getArea() < visibleRect.getArea() ) {\n\t\t\t\t\t\t// Reduce the visible rect to the intersection.\n\t\t\t\t\t\tvisibleRect = intersectionRect;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// There's no intersection, the rect is completely invisible.\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tparent = parent.parentNode;\n\t\t\t}\n\t\t}\n\n\t\treturn visibleRect;\n\t}\n\n\t/**\n\t * Checks if all property values ({@link #top}, {@link #left}, {@link #right},\n\t * {@link #bottom}, {@link #width} and {@link #height}) are the equal in both rect\n\t * instances.\n\t *\n\t * @param {module:utils/dom/rect~Rect} rect A rect instance to compare with.\n\t * @returns {Boolean} `true` when Rects are equal. `false` otherwise.\n\t */\n\tisEqual( anotherRect ) {\n\t\tfor ( const prop of rectProperties ) {\n\t\t\tif ( this[ prop ] !== anotherRect[ prop ] ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether a rect fully contains another rect instance.\n\t *\n\t * @param {module:utils/dom/rect~Rect} anotherRect\n\t * @returns {Boolean} `true` if contains, `false` otherwise.\n\t */\n\tcontains( anotherRect ) {\n\t\tconst intersectRect = this.getIntersection( anotherRect );\n\n\t\treturn !!( intersectRect && intersectRect.isEqual( anotherRect ) );\n\t}\n\n\t/**\n\t * Excludes scrollbars and CSS borders from the rect.\n\t *\n\t * * Borders are removed when {@link #_source} is an HTML element.\n\t * * Scrollbars are excluded from HTML elements and the `window`.\n\t *\n\t * @returns {module:utils/dom/rect~Rect} A rect which has been updated.\n\t */\n\texcludeScrollbarsAndBorders() {\n\t\tconst source = this._source;\n\t\tlet scrollBarWidth, scrollBarHeight;\n\n\t\tif ( isWindow( source ) ) {\n\t\t\tscrollBarWidth = source.innerWidth - source.document.documentElement.clientWidth;\n\t\t\tscrollBarHeight = source.innerHeight - source.document.documentElement.clientHeight;\n\t\t} else {\n\t\t\tconst borderWidths = getBorderWidths( this._source );\n\n\t\t\tscrollBarWidth = source.offsetWidth - source.clientWidth;\n\t\t\tscrollBarHeight = source.offsetHeight - source.clientHeight;\n\n\t\t\tthis.moveBy( borderWidths.left, borderWidths.top );\n\t\t}\n\n\t\t// Assuming LTR scrollbars. TODO: RTL.\n\t\tthis.width -= scrollBarWidth;\n\t\tthis.right -= scrollBarWidth;\n\n\t\tthis.height -= scrollBarHeight;\n\t\tthis.bottom -= scrollBarHeight;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns an array of rects of the given native DOM Range.\n\t *\n\t * @param {Range} range A native DOM range.\n\t * @returns {Array.<module:utils/dom/rect~Rect>} DOM Range rects.\n\t */\n\tstatic getDomRangeRects( range ) {\n\t\tconst rects = [];\n\t\t// Safari does not iterate over ClientRectList using for...of loop.\n\t\tconst clientRects = Array.from( range.getClientRects() );\n\n\t\tif ( clientRects.length ) {\n\t\t\tfor ( const rect of clientRects ) {\n\t\t\t\trects.push( new Rect( rect ) );\n\t\t\t}\n\t\t}\n\t\t// If there's no client rects for the Range, use parent container's bounding rect\n\t\t// instead and adjust rect's width to simulate the actual geometry of such range.\n\t\t// https://github.com/ckeditor/ckeditor5-utils/issues/153\n\t\telse {\n\t\t\tconst startContainerRect = new Rect( range.startContainer.getBoundingClientRect() );\n\t\t\tstartContainerRect.right = startContainerRect.left;\n\t\t\tstartContainerRect.width = 0;\n\n\t\t\trects.push( startContainerRect );\n\t\t}\n\n\t\treturn rects;\n\t}\n}\n\nconst rectProperties = [ 'top', 'right', 'bottom', 'left', 'width', 'height' ];\n\n// Acquires all the rect properties from the passed source.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} rect\n// @param {ClientRect|module:utils/dom/rect~Rect|Object} source\nfunction copyRectProperties( rect, source ) {\n\tfor ( const p of rectProperties ) {\n\t\trect[ p ] = source[ p ];\n\t}\n}\n\n// Checks if provided object is a <body> HTML element.\n//\n// @private\n// @param {HTMLElement|Range} elementOrRange\n// @returns {Boolean}\nfunction isBody( elementOrRange ) {\n\tif ( !isElement( elementOrRange ) ) {\n\t\treturn false;\n\t}\n\n\treturn elementOrRange === elementOrRange.ownerDocument.body;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/rect.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* global Node */\n\n/**\n * @module utils/dom/scroll\n */\n\nimport isRange from './isrange';\nimport Rect from './rect';\n\nconst utils = {};\n\n/**\n * Makes any page `HTMLElement` or `Range` (`target`) visible inside the browser viewport.\n * This helper will scroll all `target` ancestors and the web browser viewport to reveal the target to\n * the user. If the `target` is already visible, nothing will happen.\n *\n * @param {HTMLElement|Range} options.target A target, which supposed to become visible to the user.\n * @param {Number} [options.viewportOffset] An offset from the edge of the viewport (in pixels)\n * the `target` will be moved by when the viewport is scrolled. It enhances the user experience\n * by keeping the `target` some distance from the edge of the viewport and thus making it easier to\n * read or edit by the user.\n */\nexport function scrollViewportToShowTarget( { target, viewportOffset = 0 } ) {\n\tconst targetWindow = getWindow( target );\n\tlet currentWindow = targetWindow;\n\tlet currentFrame = null;\n\n\t// Iterate over all windows, starting from target's parent window up to window#top.\n\twhile ( currentWindow ) {\n\t\tlet firstAncestorToScroll;\n\n\t\t// Let's scroll target's ancestors first to reveal it. Then, once the ancestor scrolls\n\t\t// settled down, the algorithm can eventually scroll the viewport of the current window.\n\t\t//\n\t\t// Note: If the current window is target's **original** window (e.g. the first one),\n\t\t// start scrolling the closest parent of the target. If not, scroll the closest parent\n\t\t// of an iframe that resides in the current window.\n\t\tif ( currentWindow == targetWindow ) {\n\t\t\tfirstAncestorToScroll = getParentElement( target );\n\t\t} else {\n\t\t\tfirstAncestorToScroll = getParentElement( currentFrame );\n\t\t}\n\n\t\t// Scroll the target's ancestors first. Once done, scrolling the viewport is easy.\n\t\tscrollAncestorsToShowRect( firstAncestorToScroll, () => {\n\t\t\t// Note: If the target does not belong to the current window **directly**,\n\t\t\t// i.e. it resides in an iframe belonging to the window, obtain the target's rect\n\t\t\t// in the coordinates of the current window. By default, a Rect returns geometry\n\t\t\t// relative to the current window's viewport. To make it work in a parent window,\n\t\t\t// it must be shifted.\n\t\t\treturn getRectRelativeToWindow( target, currentWindow );\n\t\t} );\n\n\t\t// Obtain the rect of the target after it has been scrolled within its ancestors.\n\t\t// It's time to scroll the viewport.\n\t\tconst targetRect = getRectRelativeToWindow( target, currentWindow );\n\n\t\tscrollWindowToShowRect( currentWindow, targetRect, viewportOffset );\n\n\t\tif ( currentWindow.parent != currentWindow ) {\n\t\t\t// Keep the reference to the <iframe> element the \"previous current window\" was\n\t\t\t// rendered within. It will be useful to recalculate the rect of the target\n\t\t\t// in the parent window's relative geometry. The target's rect must be shifted\n\t\t\t// by it's iframe's position.\n\t\t\tcurrentFrame = currentWindow.frameElement;\n\t\t\tcurrentWindow = currentWindow.parent;\n\t\t} else {\n\t\t\tcurrentWindow = null;\n\t\t}\n\t}\n}\n\n/**\n * Makes any page `HTMLElement` or `Range` (target) visible within its scrollable ancestors,\n * e.g. if they have `overflow: scroll` CSS style.\n *\n * @param {HTMLElement|Range} target A target, which supposed to become visible to the user.\n */\nexport function scrollAncestorsToShowTarget( target ) {\n\tconst targetParent = getParentElement( target );\n\n\tscrollAncestorsToShowRect( targetParent, () => {\n\t\treturn new Rect( target );\n\t} );\n}\n\n// TODO: Using a property value shorthand in the top of the file\n// causes JSDoc to throw errors. See https://github.com/cksource/docs-builder/issues/75.\nObject.assign( utils, {\n\tscrollViewportToShowTarget,\n\tscrollAncestorsToShowTarget\n} );\n\n// Makes a given rect visible within its parent window.\n//\n// Note: Avoid the situation where the caret is still in the viewport, but totally\n// at the edge of it. In such situation, if it moved beyond the viewport in the next\n// action e.g. after paste, the scrolling would move it to the viewportOffset level\n// and it all would look like the caret visually moved up/down:\n//\n// 1.\n//\t\t| foo[]\n//\t\t| <--- N px of space below the caret\n//\t\t+---------------------------------...\n//\n// 2. *paste*\n// 3.\n//\t\t|\n//\t\t|\n//\t\t+-foo-----------------------------...\n//\t\t bar[] <--- caret below viewport, scrolling...\n//\n// 4. *scrolling*\n// 5.\n//\t\t|\n//\t\t| foo\n//\t\t| bar[] <--- caret precisely at the edge\n//\t\t+---------------------------------...\n//\n// To prevent this, this method checks the rects moved by the viewportOffset to cover\n// the upper/lower edge of the viewport. It makes sure if the action repeats, there's\n// no twitching it's a purely visual improvement:\n//\n// 5. (after fix)\n//\t\t|\n//\t\t| foo\n//\t\t| bar[]\n//\t\t| <--- N px of space below the caret\n//\t\t+---------------------------------...\n//\n// @private\n// @param {Window} window A window which is scrolled to reveal the rect.\n// @param {module:utils/dom/rect~Rect} rect A rect which is to be revealed.\n// @param {Number} viewportOffset See scrollViewportToShowTarget.\nfunction scrollWindowToShowRect( window, rect, viewportOffset ) {\n\tconst targetShiftedDownRect = rect.clone().moveBy( 0, viewportOffset );\n\tconst targetShiftedUpRect = rect.clone().moveBy( 0, -viewportOffset );\n\tconst viewportRect = new Rect( window ).excludeScrollbarsAndBorders();\n\n\tconst rects = [ targetShiftedUpRect, targetShiftedDownRect ];\n\n\tif ( !rects.every( rect => viewportRect.contains( rect ) ) ) {\n\t\tlet { scrollX, scrollY } = window;\n\n\t\tif ( isAbove( targetShiftedUpRect, viewportRect ) ) {\n\t\t\tscrollY -= viewportRect.top - rect.top + viewportOffset;\n\t\t} else if ( isBelow( targetShiftedDownRect, viewportRect ) ) {\n\t\t\tscrollY += rect.bottom - viewportRect.bottom + viewportOffset;\n\t\t}\n\n\t\t// TODO: Web browsers scroll natively to place the target in the middle\n\t\t// of the viewport. It's not a very popular case, though.\n\t\tif ( isLeftOf( rect, viewportRect ) ) {\n\t\t\tscrollX -= viewportRect.left - rect.left + viewportOffset;\n\t\t} else if ( isRightOf( rect, viewportRect ) ) {\n\t\t\tscrollX += rect.right - viewportRect.right + viewportOffset;\n\t\t}\n\n\t\twindow.scrollTo( scrollX, scrollY );\n\t}\n}\n\n// Recursively scrolls element ancestors to visually reveal a rect.\n//\n// @private\n// @param {HTMLElement} A parent The first ancestors to start scrolling.\n// @param {Function} getRect A function which returns the Rect, which is to be revealed.\nfunction scrollAncestorsToShowRect( parent, getRect ) {\n\tconst parentWindow = getWindow( parent );\n\tlet parentRect, targetRect;\n\n\twhile ( parent != parentWindow.document.body ) {\n\t\ttargetRect = getRect();\n\t\tparentRect = new Rect( parent ).excludeScrollbarsAndBorders();\n\n\t\tif ( !parentRect.contains( targetRect ) ) {\n\t\t\tif ( isAbove( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollTop -= parentRect.top - targetRect.top;\n\t\t\t} else if ( isBelow( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollTop += targetRect.bottom - parentRect.bottom;\n\t\t\t}\n\n\t\t\tif ( isLeftOf( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollLeft -= parentRect.left - targetRect.left;\n\t\t\t} else if ( isRightOf( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollLeft += targetRect.right - parentRect.right;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parentNode;\n\t}\n}\n\n// Determines if a given `Rect` extends beyond the bottom edge of the second `Rect`.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} firstRect\n// @param {module:utils/dom/rect~Rect} secondRect\nfunction isBelow( firstRect, secondRect ) {\n\treturn firstRect.bottom > secondRect.bottom;\n}\n\n// Determines if a given `Rect` extends beyond the top edge of the second `Rect`.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} firstRect\n// @param {module:utils/dom/rect~Rect} secondRect\nfunction isAbove( firstRect, secondRect ) {\n\treturn firstRect.top < secondRect.top;\n}\n\n// Determines if a given `Rect` extends beyond the left edge of the second `Rect`.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} firstRect\n// @param {module:utils/dom/rect~Rect} secondRect\nfunction isLeftOf( firstRect, secondRect ) {\n\treturn firstRect.left < secondRect.left;\n}\n\n// Determines if a given `Rect` extends beyond the right edge of the second `Rect`.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} firstRect\n// @param {module:utils/dom/rect~Rect} secondRect\nfunction isRightOf( firstRect, secondRect ) {\n\treturn firstRect.right > secondRect.right;\n}\n\n// Returns the closest window of an element or range.\n//\n// @private\n// @param {HTMLElement|Range} firstRect\n// @returns {Window}\nfunction getWindow( elementOrRange ) {\n\tif ( isRange( elementOrRange ) ) {\n\t\treturn elementOrRange.startContainer.ownerDocument.defaultView;\n\t} else {\n\t\treturn elementOrRange.ownerDocument.defaultView;\n\t}\n}\n\n// Returns the closest parent of an element or DOM range.\n//\n// @private\n// @param {HTMLElement|Range} firstRect\n// @returns {HTMLelement}\nfunction getParentElement( elementOrRange ) {\n\tif ( isRange( elementOrRange ) ) {\n\t\tlet parent = elementOrRange.commonAncestorContainer;\n\n\t\t// If a Range is attached to the Text, use the closest element ancestor.\n\t\tif ( parent.nodeType == Node.TEXT_NODE ) {\n\t\t\tparent = parent.parentNode;\n\t\t}\n\n\t\treturn parent;\n\t} else {\n\t\treturn elementOrRange.parentNode;\n\t}\n}\n\n// Returns the rect of an element or range residing in an iframe.\n// The result rect is relative to the geometry of the passed window instance.\n//\n// @private\n// @param {HTMLElement|Range} target Element or range which rect should be returned.\n// @param {Window} relativeWindow A window the rect should be relative to.\n// @returns {module:utils/dom/rect~Rect}\nfunction getRectRelativeToWindow( target, relativeWindow ) {\n\tconst targetWindow = getWindow( target );\n\tconst rect = new Rect( target );\n\n\tif ( targetWindow === relativeWindow ) {\n\t\treturn rect;\n\t} else {\n\t\tlet currentWindow = targetWindow;\n\n\t\twhile ( currentWindow != relativeWindow ) {\n\t\t\tconst frame = currentWindow.frameElement;\n\t\t\tconst frameRect = new Rect( frame ).excludeScrollbarsAndBorders();\n\n\t\t\trect.moveBy( frameRect.left, frameRect.top );\n\n\t\t\tcurrentWindow = currentWindow.parent;\n\t\t}\n\t}\n\n\treturn rect;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/scroll.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/document\n */\n\nimport Selection from './selection';\nimport Renderer from './renderer';\nimport DomConverter from './domconverter';\nimport RootEditableElement from './rooteditableelement';\nimport { injectQuirksHandling } from './filler';\nimport { injectUiElementHandling } from './uielement';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport MutationObserver from './observer/mutationobserver';\nimport SelectionObserver from './observer/selectionobserver';\nimport FocusObserver from './observer/focusobserver';\nimport KeyObserver from './observer/keyobserver';\nimport FakeSelectionObserver from './observer/fakeselectionobserver';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport { scrollViewportToShowTarget } from '@ckeditor/ckeditor5-utils/src/dom/scroll';\n\n/**\n * Document class creates an abstract layer over the content editable area.\n * It combines the actual tree of view elements, tree of DOM elements,\n * {@link module:engine/view/domconverter~DomConverter DOM Converter}, {@link module:engine/view/renderer~Renderer renderer} and all\n * {@link module:engine/view/observer/observer~Observer observers}.\n *\n * If you want to only transform the tree of view elements to the DOM elements you can use the\n * {@link module:engine/view/domconverter~DomConverter DomConverter}.\n *\n * Note that the following observers are added by the class constructor and are always available:\n *\n * * {@link module:engine/view/observer/mutationobserver~MutationObserver},\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 *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Document {\n\t/**\n\t * Creates a Document instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Roots of the DOM tree. Map on the `HTMLElement`s with roots names as keys.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Map} module:engine/view/document~Document#domRoots\n\t\t */\n\t\tthis.domRoots = new Map();\n\n\t\t/**\n\t\t * Selection done on this document.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/selection~Selection} module:engine/view/document~Document#selection\n\t\t */\n\t\tthis.selection = new Selection();\n\n\t\t/**\n\t\t * Instance of the {@link module:engine/view/domconverter~DomConverter domConverter} use by\n\t\t * {@link module:engine/view/document~Document#renderer renderer}\n\t\t * and {@link module:engine/view/observer/observer~Observer observers}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/domconverter~DomConverter} module:engine/view/document~Document#domConverter\n\t\t */\n\t\tthis.domConverter = new DomConverter();\n\n\t\t/**\n\t\t * Roots of the view tree. Map of the {module:engine/view/element~Element view elements} with roots names as keys.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Map} module:engine/view/document~Document#roots\n\t\t */\n\t\tthis.roots = new Map();\n\n\t\t/**\n\t\t * Defines whether document is in read-only mode.\n\t\t *\n\t\t * When document is read-ony then all roots are read-only as well and caret placed inside this root is hidden.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * True if document is focused.\n\t\t *\n\t\t * This property is updated by the {@link module:engine/view/observer/focusobserver~FocusObserver}.\n\t\t * If the {@link module:engine/view/observer/focusobserver~FocusObserver} is disabled this property will not change.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} module:engine/view/document~Document#isFocused\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * Instance of the {@link module:engine/view/document~Document#renderer renderer}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/renderer~Renderer} module:engine/view/document~Document#renderer\n\t\t */\n\t\tthis.renderer = new Renderer( this.domConverter, this.selection );\n\t\tthis.renderer.bind( 'isFocused' ).to( this );\n\n\t\t/**\n\t\t * Map of registered {@link module:engine/view/observer/observer~Observer observers}.\n\t\t *\n\t\t * @private\n\t\t * @member {Map.<Function, module:engine/view/observer/observer~Observer>} module:engine/view/document~Document#_observers\n\t\t */\n\t\tthis._observers = new Map();\n\n\t\t// Add default observers.\n\t\tthis.addObserver( MutationObserver );\n\t\tthis.addObserver( SelectionObserver );\n\t\tthis.addObserver( FocusObserver );\n\t\tthis.addObserver( KeyObserver );\n\t\tthis.addObserver( FakeSelectionObserver );\n\n\t\tinjectQuirksHandling( this );\n\t\tinjectUiElementHandling( this );\n\n\t\tthis.decorate( 'render' );\n\t}\n\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 module:engine/view/document~Document#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 {Function} Observer 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 {module:engine/view/observer/observer~Observer} Added observer instance.\n\t */\n\taddObserver( Observer ) {\n\t\tlet observer = this._observers.get( Observer );\n\n\t\tif ( observer ) {\n\t\t\treturn observer;\n\t\t}\n\n\t\tobserver = new Observer( this );\n\n\t\tthis._observers.set( Observer, observer );\n\n\t\tfor ( const [ name, domElement ] of this.domRoots ) {\n\t\t\tobserver.observe( domElement, name );\n\t\t}\n\n\t\tobserver.enable();\n\n\t\treturn observer;\n\t}\n\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 {Function} Observer The constructor of an observer to get.\n\t * @returns {module:engine/view/observer/observer~Observer|undefined} Observer instance or undefined.\n\t */\n\tgetObserver( Observer ) {\n\t\treturn this._observers.get( Observer );\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/view/document~Document#roots view root element}.\n\t *\n\t * If the DOM element is passed as a first parameter it will be automatically\n\t * {@link module:engine/view/document~Document#attachDomRoot attached}:\n\t *\n\t *\t\tdocument.createRoot( document.querySelector( 'div#editor' ) ); // Will call document.attachDomRoot.\n\t *\n\t * However, if the string is passed, then only the view element will be created and the DOM element have to be\n\t * attached separately:\n\t *\n\t *\t\tdocument.createRoot( 'body' );\n\t *\t\tdocument.attachDomRoot( document.querySelector( 'body#editor' ) );\n\t *\n\t * In both cases, {@link module:engine/view/rooteditableelement~RootEditableElement#rootName element name} is always\n\t * transformed to lower\n\t * case.\n\t *\n\t * @param {Element|String} domRoot DOM root element or the tag name of view root element if the DOM element will be\n\t * attached later.\n\t * @param {String} [name='main'] Name of the root.\n\t * @returns {module:engine/view/rooteditableelement~RootEditableElement} The created view root element.\n\t */\n\tcreateRoot( domRoot, name = 'main' ) {\n\t\tconst rootTag = typeof domRoot == 'string' ? domRoot : domRoot.tagName;\n\n\t\tconst viewRoot = new RootEditableElement( rootTag.toLowerCase(), name );\n\t\tviewRoot.document = this;\n\n\t\tthis.roots.set( name, viewRoot );\n\n\t\t// Mark changed nodes in the renderer.\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\n\t\tif ( this.domConverter.isElement( domRoot ) ) {\n\t\t\tthis.attachDomRoot( domRoot, name );\n\t\t}\n\n\t\treturn viewRoot;\n\t}\n\n\t/**\n\t * Attaches DOM root element to the view element and enable all observers on that element. This method also\n\t * {@link module:engine/view/renderer~Renderer#markToSync mark element} to be synchronized with the view what means that all child\n\t * nodes will be removed and replaced with content of the view root.\n\t *\n\t * Note that {@link module:engine/view/document~Document#createRoot} will call this method automatically if the DOM element is\n\t * passed to it.\n\t *\n\t * @param {Element|String} domRoot DOM root element.\n\t * @param {String} [name='main'] Name of the root.\n\t */\n\tattachDomRoot( domRoot, name = 'main' ) {\n\t\tconst viewRoot = this.getRoot( name );\n\n\t\tthis.domRoots.set( name, domRoot );\n\n\t\tthis.domConverter.bindElements( domRoot, viewRoot );\n\n\t\tthis.renderer.markToSync( 'children', viewRoot );\n\t\tthis.renderer.domDocuments.add( domRoot.ownerDocument );\n\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.observe( domRoot, name );\n\t\t}\n\t}\n\n\t/**\n\t * Gets a {@link module:engine/view/document~Document#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 {String} [name='main'] Name of the root.\n\t * @returns {module:engine/view/rooteditableelement~RootEditableElement} The view root element with the specified name.\n\t */\n\tgetRoot( name = 'main' ) {\n\t\treturn this.roots.get( name );\n\t}\n\n\t/**\n\t * Gets DOM root element.\n\t *\n\t * @param {String} [name='main'] Name of the root.\n\t * @returns {Element} DOM root element instance.\n\t */\n\tgetDomRoot( name = 'main' ) {\n\t\treturn this.domRoots.get( name );\n\t}\n\n\t/**\n\t * Renders all changes. In order to avoid triggering the observers (e.g. mutations) all observers are disabled\n\t * before rendering and re-enabled after that.\n\t *\n\t * @fires render\n\t */\n\trender() {\n\t\tthis.disableObservers();\n\t\tthis.renderer.render();\n\t\tthis.enableObservers();\n\t}\n\n\t/**\n\t * Focuses document. It will focus {@link module:engine/view/editableelement~EditableElement EditableElement} that is currently having\n\t * selection inside.\n\t */\n\tfocus() {\n\t\tif ( !this.isFocused ) {\n\t\t\tconst editable = this.selection.editableElement;\n\n\t\t\tif ( editable ) {\n\t\t\t\tthis.domConverter.focus( editable );\n\t\t\t\tthis.render();\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * Before focusing view document, selection should be placed inside one of the view's editables.\n\t\t\t\t * Normally its selection will be converted from model document (which have default selection), but\n\t\t\t\t * when using view document on its own, we need to manually place selection before focusing it.\n\t\t\t\t *\n\t\t\t\t * @error view-focus-no-selection\n\t\t\t\t */\n\t\t\t\tlog.warn( 'view-focus-no-selection: There is no selection in any editable to focus.' );\n\t\t\t}\n\t\t}\n\t}\n\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\tscrollToTheSelection() {\n\t\tconst range = this.selection.getFirstRange();\n\n\t\tif ( range ) {\n\t\t\tscrollViewportToShowTarget( {\n\t\t\t\ttarget: this.domConverter.viewRangeToDom( range ),\n\t\t\t\tviewportOffset: 20\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Disables all added observers.\n\t */\n\tdisableObservers() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Enables all added observers.\n\t */\n\tenableObservers() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.enable();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all observers created by view `Document`.\n\t */\n\tdestroy() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.destroy();\n\t\t}\n\t}\n}\n\nmix( Document, ObservableMixin );\n\n/**\n * Enum representing type of the change.\n *\n * Possible values:\n *\n * * `children` - for child list changes,\n * * `attributes` - for element attributes changes,\n * * `text` - for text nodes changes.\n *\n * @typedef {String} module:engine/view/document~ChangeType\n */\n\n/**\n * Fired when {@link #render render} method is called. Actual rendering is executed as a listener to\n * this event with default priority. This way other listeners can be used to run code before or after rendering.\n *\n * @event render\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/document.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * Contains {@link module:engine/view/selection~Selection view selection}\n * to {@link module:engine/model/selection~Selection model selection} conversion helpers.\n *\n * @module engine/conversion/view-selection-to-model-converters\n */\n\nimport ModelSelection from '../model/selection';\n\n/**\n * Function factory, creates a callback function which converts a {@link module:engine/view/selection~Selection view selection} taken\n * from the {@link module:engine/view/document~Document#event:selectionChange} event\n * and sets in on the {@link module:engine/model/document~Document#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 *\t\tview.document.on( 'selectionChange', convertSelectionChange( modelDocument, mapper ) );\n *\n * @param {module:engine/model/document~Document} modelDocument Model document on which selection should be updated.\n * @param {module:engine/conversion/mapper~Mapper} mapper Conversion mapper.\n * @returns {Function} {@link module:engine/view/document~Document#event:selectionChange} callback function.\n */\nexport function convertSelectionChange( modelDocument, mapper ) {\n\treturn ( evt, data ) => {\n\t\tconst viewSelection = data.newSelection;\n\t\tconst modelSelection = new ModelSelection();\n\n\t\tconst ranges = [];\n\n\t\tfor ( const viewRange of viewSelection.getRanges() ) {\n\t\t\tranges.push( mapper.toModelRange( viewRange ) );\n\t\t}\n\n\t\tmodelSelection.setRanges( ranges, viewSelection.isBackward );\n\n\t\tif ( !modelSelection.isEqual( modelDocument.selection ) ) {\n\t\t\tmodelDocument.enqueueChanges( () => {\n\t\t\t\tmodelDocument.selection.setTo( modelSelection );\n\t\t\t} );\n\t\t}\n\t};\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/view-selection-to-model-converters.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport ViewElement from '../view/element';\nimport ViewRange from '../view/range';\nimport viewWriter from '../view/writer';\nimport { createViewElementFromHighlightDescriptor } from './model-to-view-converters';\n\n/**\n * Contains {@link module:engine/model/selection~Selection model selection} to\n * {@link module:engine/view/selection~Selection view selection} converters for\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}.\n *\n * @module engine/conversion/model-selection-to-view-converters\n */\n\n/**\n * Function factory, creates a converter that converts non-collapsed {@link module:engine/model/selection~Selection model selection} to\n * {@link module:engine/view/selection~Selection view selection}. The converter consumes appropriate value from `consumable` object\n * and maps model positions from selection to view positions.\n *\n *\t\tmodelDispatcher.on( 'selection', convertRangeSelection() );\n *\n * @returns {Function} Selection converter.\n */\nexport function convertRangeSelection() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst selection = data.selection;\n\n\t\tif ( selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !consumable.consume( selection, 'selection' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconversionApi.viewSelection.removeAllRanges();\n\n\t\tfor ( const range of selection.getRanges() ) {\n\t\t\tconst viewRange = conversionApi.mapper.toViewRange( range );\n\t\t\tconversionApi.viewSelection.addRange( viewRange, selection.isBackward );\n\t\t}\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts collapsed {@link module:engine/model/selection~Selection model selection} to\n * {@link module:engine/view/selection~Selection view selection}. The converter consumes appropriate value from `consumable` object,\n * maps model selection position to view position and breaks {@link module:engine/view/attributeelement~AttributeElement attribute elements}\n * at the selection position.\n *\n *\t\tmodelDispatcher.on( 'selection', convertCollapsedSelection() );\n *\n * Example of view state before and after converting collapsed selection:\n *\n *\t\t <p><strong>f^oo<strong>bar</p>\n *\t\t-> <p><strong>f</strong>^<strong>oo</strong>bar</p>\n *\n * By breaking attribute elements like `<strong>`, selection is in correct element. See also complementary\n * {@link module:engine/conversion/model-selection-to-view-converters~convertSelectionAttribute attribute converter}\n * for selection attributes,\n * which wraps collapsed selection into view elements. Those converters together ensure, that selection ends up in\n * appropriate attribute elements.\n *\n * See also {@link module:engine/conversion/model-selection-to-view-converters~clearAttributes} which does a clean-up\n * by merging attributes.\n *\n * @returns {Function} Selection converter.\n */\nexport function convertCollapsedSelection() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst selection = data.selection;\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !consumable.consume( selection, 'selection' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelPosition = selection.getFirstPosition();\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( modelPosition );\n\t\tconst brokenPosition = viewWriter.breakAttributes( viewPosition );\n\n\t\tconversionApi.viewSelection.removeAllRanges();\n\t\tconversionApi.viewSelection.addRange( new ViewRange( brokenPosition, brokenPosition ) );\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts {@link module:engine/model/selection~Selection model selection} attributes to\n * {@link module:engine/view/attributeelement~AttributeElement view attribute elements}. The converter works only for collapsed selection.\n * The converter consumes appropriate value from `consumable` object, maps model selection position to view position and\n * wraps that position into a view attribute element.\n *\n * The wrapping node depends on passed parameter. If {@link module:engine/view/element~Element} was passed, it will be cloned and\n * the copy will become the wrapping element. If `Function` is provided, it is passed all the parameters of the\n * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:selectionAttribute selectionAttribute event}.\n * It's expected that the function returns a {@link module:engine/view/attributeelement~AttributeElement}.\n * The result of the function will be the wrapping element.\n *\n *\t\tmodelDispatcher.on( 'selectionAttribute:italic', convertSelectionAttribute( new ViewAttributeElement( 'em' ) ) );\n *\n *\t\tfunction styleElementCreator( styleValue ) {\n *\t\t\tif ( styleValue == 'important' ) {\n *\t\t\t\treturn new ViewAttributeElement( 'strong', { style: 'text-transform:uppercase;' } );\n *\t\t\t} else if ( styleValue == 'gold' ) {\n *\t\t\t\treturn new ViewAttributeElement( 'span', { style: 'color:yellow;' } );\n *\t\t\t}\n *\t\t}\n *\t\tmodelDispatcher.on( 'selectionAttribute:style', convertSelectionAttribute( styleCreator ) );\n *\t\tmodelDispatcher.on( 'selection', convertCollapsedSelection() );\n *\t\tmodelDispatcher.on( 'selectionAttribute:italic', convertSelectionAttribute( new ViewAttributeElement( 'em' ) ) );\n *\t\tmodelDispatcher.on( 'selectionAttribute:bold', convertSelectionAttribute( new ViewAttributeElement( 'strong' ) ) );\n *\n * Example of view states before and after converting collapsed selection:\n *\n *\t\t <p><em>f^oo</em>bar</p>\n *\t\t-> <p><em>f</em>^<em>oo</em>bar</p>\n *\t\t-> <p><em>f^oo</em>bar</p>\n *\n * Example of view state after converting collapsed selection. The scenario is: selection is inside bold text (`<strong>` element)\n * but it does not have bold attribute itself and has italic attribute instead (let's assume that user turned off bold and turned\n * on italic with selection collapsed):\n *\n *\t\t <p><strong>f^oo<strong>bar</p>\n *\t\t-> <p><strong>f</strong>^<strong>oo<strong>bar</p>\n *\t\t-> <p><strong>f</strong><em>^</em><strong>oo</strong>bar</p>\n *\n * In first example, nothing has changed, because first `<em>` element got broken by `convertCollapsedSelection()` converter,\n * but then it got wrapped-back by `convertSelectionAttribute()` converter. In second example, notice how `<strong>` element\n * is broken to prevent putting selection in it, since selection has no `bold` attribute.\n *\n * @param {module:engine/view/attributeelement~AttributeElement|Function} elementCreator View element,\n * or function returning a view element, which will be used for wrapping.\n * @returns {Function} Selection converter.\n */\nexport function convertSelectionAttribute( elementCreator ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst viewElement = elementCreator instanceof ViewElement ?\n\t\t\telementCreator.clone( true ) :\n\t\t\telementCreator( data.value, data, data.selection, consumable, conversionApi );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst consumableName = 'selectionAttribute:' + data.key;\n\n\t\twrapCollapsedSelectionPosition( data.selection, conversionApi.viewSelection, viewElement, consumable, consumableName );\n\t};\n}\n\n/**\n * Performs similar conversion as {@link ~convertSelectionAttribute}, but depends on a marker name of a marker in which\n * collapsed selection is placed.\n *\n *\t\tmodelDispatcher.on( 'selectionMarker:searchResult', convertSelectionMarker( { class: 'search' } ) );\n *\n * @see module:engine/conversion/model-selection-to-view-converters~convertSelectionAttribute\n * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor|Function} highlightDescriptor Highlight\n * descriptor object or function returning a descriptor object.\n * @returns {Function} Selection converter.\n */\nexport function convertSelectionMarker( highlightDescriptor ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst descriptor = typeof highlightDescriptor == 'function' ?\n\t\t\thighlightDescriptor( data, consumable, conversionApi ) :\n\t\t\thighlightDescriptor;\n\n\t\tif ( !descriptor ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !descriptor.id ) {\n\t\t\tdescriptor.id = data.markerName;\n\t\t}\n\n\t\tconst viewElement = createViewElementFromHighlightDescriptor( descriptor );\n\t\tconst consumableName = 'selectionMarker:' + data.markerName;\n\n\t\twrapCollapsedSelectionPosition( data.selection, conversionApi.viewSelection, viewElement, consumable, consumableName );\n\t};\n}\n\n// Helper function for `convertSelectionAttribute` and `convertSelectionMarker`, which perform similar task.\nfunction wrapCollapsedSelectionPosition( modelSelection, viewSelection, viewElement, consumable, consumableName ) {\n\tif ( !modelSelection.isCollapsed ) {\n\t\treturn;\n\t}\n\n\tif ( !consumable.consume( modelSelection, consumableName ) ) {\n\t\treturn;\n\t}\n\n\tlet viewPosition = viewSelection.getFirstPosition();\n\n\t// This hack is supposed to place attribute element *after* all ui elements if the attribute element would be\n\t// the only non-ui child and thus receive a block filler.\n\t// This is needed to properly render ui elements. Block filler is a <br /> element. If it is placed before\n\t// UI element, the ui element will most probably be incorrectly rendered (in next line). #1072.\n\tif ( shouldPushAttributeElement( viewPosition.parent ) ) {\n\t\tviewPosition = viewPosition.getLastMatchingPosition( value => value.item.is( 'uiElement' ) );\n\t}\n\t// End of hack.\n\n\tviewPosition = viewWriter.wrapPosition( viewPosition, viewElement );\n\n\tviewSelection.removeAllRanges();\n\tviewSelection.addRange( new ViewRange( viewPosition, viewPosition ) );\n}\n\nfunction shouldPushAttributeElement( parent ) {\n\tif ( !parent.is( 'element' ) ) {\n\t\treturn false;\n\t}\n\n\tfor ( const child of parent.getChildren() ) {\n\t\tif ( !child.is( 'uiElement' ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Function factory, creates a converter that clears artifacts after the previous\n * {@link module:engine/model/selection~Selection model selection} conversion. It removes all empty\n * {@link module:engine/view/attributeelement~AttributeElement view attribute elements} and merge sibling attributes at all start and end\n * positions of all ranges.\n *\n *\t\t <p><strong>^</strong></p>\n *\t\t-> <p>^</p>\n *\n *\t\t <p><strong>foo</strong>^<strong>bar</strong>bar</p>\n *\t\t-> <p><strong>foo^bar<strong>bar</p>\n *\n *\t\t <p><strong>foo</strong><em>^</em><strong>bar</strong>bar</p>\n *\t\t-> <p><strong>foo^bar<strong>bar</p>\n *\n * This listener should be assigned before any converter for the new selection:\n *\n *\t\tmodelDispatcher.on( 'selection', clearAttributes() );\n *\n * See {@link module:engine/conversion/model-selection-to-view-converters~convertCollapsedSelection}\n * which do the opposite by breaking attributes in the selection position.\n *\n * @returns {Function} Selection converter.\n */\nexport function clearAttributes() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tfor ( const range of conversionApi.viewSelection.getRanges() ) {\n\t\t\t// Not collapsed selection should not have artifacts.\n\t\t\tif ( range.isCollapsed ) {\n\t\t\t\t// Position might be in the node removed by the view writer.\n\t\t\t\tif ( range.end.parent.document ) {\n\t\t\t\t\tviewWriter.mergeAttributes( range.start );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconversionApi.viewSelection.removeAllRanges();\n\t};\n}\n\n/**\n * Function factory, creates a converter that clears fake selection marking after the previous\n * {@link module:engine/model/selection~Selection model selection} conversion.\n */\nexport function clearFakeSelection() {\n\treturn ( evt, data, consumable, conversionApi ) => conversionApi.viewSelection.setFake( false );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/model-selection-to-view-converters.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/controller/editingcontroller\n */\n\nimport ViewDocument from '../view/document';\nimport Mapper from '../conversion/mapper';\nimport ModelConversionDispatcher from '../conversion/modelconversiondispatcher';\nimport {\n\tinsertText,\n\tremove\n} from '../conversion/model-to-view-converters';\nimport { convertSelectionChange } from '../conversion/view-selection-to-model-converters';\nimport {\n\tconvertRangeSelection,\n\tconvertCollapsedSelection,\n\tclearAttributes,\n\tclearFakeSelection\n} from '../conversion/model-selection-to-view-converters';\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Controller for the editing pipeline. The editing pipeline controls {@link ~EditingController#model model} rendering,\n * including selection handling. It also creates {@link ~EditingController#view view document} which build a\n * browser-independent virtualization over the DOM elements. Editing controller also attach default converters.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class EditingController {\n\t/**\n\t * Creates editing controller instance.\n\t *\n\t * @param {module:engine/model/document~Document} model Document model.\n\t */\n\tconstructor( model ) {\n\t\t/**\n\t\t * Document model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/document~Document}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * View document.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/document~Document}\n\t\t */\n\t\tthis.view = new ViewDocument();\n\n\t\t/**\n\t\t * Mapper which describes model-view binding.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/mapper~Mapper}\n\t\t */\n\t\tthis.mapper = new Mapper();\n\n\t\t/**\n\t\t * Model to view conversion dispatcher, which converts changes from the model to\n\t\t * {@link #view editing view}.\n\t\t *\n\t\t * To attach model to view converter to the editing pipeline you need to add lister to this property:\n\t\t *\n\t\t *\t\tediting.modelToView( 'insert:$element', customInsertConverter );\n\t\t *\n\t\t * Or use {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder}:\n\t\t *\n\t\t *\t\tbuildModelConverter().for( editing.modelToView ).fromAttribute( 'bold' ).toElement( 'b' );\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher} #modelToView\n\t\t */\n\t\tthis.modelToView = new ModelConversionDispatcher( this.model, {\n\t\t\tmapper: this.mapper,\n\t\t\tviewSelection: this.view.selection\n\t\t} );\n\n\t\t// Convert changes in model to view.\n\t\tthis.listenTo( this.model, 'change', ( evt, type, changes ) => {\n\t\t\tthis.modelToView.convertChange( type, changes );\n\t\t}, { priority: 'low' } );\n\n\t\t// Convert model selection to view.\n\t\tthis.listenTo( this.model, 'changesDone', () => {\n\t\t\tconst selection = this.model.selection;\n\n\t\t\tthis.modelToView.convertSelection( selection );\n\t\t\tthis.view.render();\n\t\t}, { priority: 'low' } );\n\n\t\t// Convert model markers changes.\n\t\tthis.listenTo( this.model.markers, 'add', ( evt, marker ) => {\n\t\t\tthis.modelToView.convertMarker( 'addMarker', marker.name, marker.getRange() );\n\t\t} );\n\n\t\tthis.listenTo( this.model.markers, 'remove', ( evt, marker ) => {\n\t\t\tthis.modelToView.convertMarker( 'removeMarker', marker.name, marker.getRange() );\n\t\t} );\n\n\t\t// Convert view selection to model.\n\t\tthis.listenTo( this.view, 'selectionChange', convertSelectionChange( this.model, this.mapper ) );\n\n\t\t// Attach default content converters.\n\t\tthis.modelToView.on( 'insert:$text', insertText(), { priority: 'lowest' } );\n\t\tthis.modelToView.on( 'remove', remove(), { priority: 'low' } );\n\n\t\t// Attach default selection converters.\n\t\tthis.modelToView.on( 'selection', clearAttributes(), { priority: 'low' } );\n\t\tthis.modelToView.on( 'selection', clearFakeSelection(), { priority: 'low' } );\n\t\tthis.modelToView.on( 'selection', convertRangeSelection(), { priority: 'low' } );\n\t\tthis.modelToView.on( 'selection', convertCollapsedSelection(), { priority: 'low' } );\n\t}\n\n\t/**\n\t * {@link module:engine/view/document~Document#createRoot Creates} a view root\n\t * and {@link module:engine/conversion/mapper~Mapper#bindElements binds}\n\t * the model root with view root and and view root with DOM element:\n\t *\n\t *\t\tediting.createRoot( document.querySelector( div#editor ) );\n\t *\n\t * If the DOM element is not available at the time you want to create a view root, for instance it is iframe body\n\t * element, it is possible to create view element and bind the DOM element later:\n\t *\n\t *\t\tediting.createRoot( 'body' );\n\t *\t\tediting.view.attachDomRoot( iframe.contentDocument.body );\n\t *\n\t * @param {Element|String} domRoot DOM root element or the name of view root element if the DOM element will be\n\t * attached later.\n\t * @param {String} [name='main'] Root name.\n\t * @returns {module:engine/view/containerelement~ContainerElement} View root element.\n\t */\n\tcreateRoot( domRoot, name = 'main' ) {\n\t\tconst viewRoot = this.view.createRoot( domRoot, name );\n\t\tconst modelRoot = this.model.getRoot( name );\n\n\t\tthis.mapper.bindElements( modelRoot, viewRoot );\n\n\t\treturn viewRoot;\n\t}\n\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}\n\nmix( EditingController, ObservableMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/controller/editingcontroller.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals HTMLTextAreaElement */\n\n/**\n * @module utils/dom/getdatafromelement\n */\n\n/**\n * Gets data from a given source element.\n *\n * @param {HTMLElement} el The element from which the data will be retrieved.\n * @returns {String} The data string.\n */\nexport default function getDataFromElement( el ) {\n\tif ( el instanceof HTMLTextAreaElement ) {\n\t\treturn el.value;\n\t}\n\n\treturn el.innerHTML;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/getdatafromelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/setdatainelement\n */\n\n/* globals HTMLTextAreaElement */\n\n/**\n * Sets data in a given element.\n *\n * @param {HTMLElement} el The element in which the data will be set.\n * @param {String} data The data string.\n */\nexport default function setDataInElement( el, data ) {\n\tif ( el instanceof HTMLTextAreaElement ) {\n\t\tel.value = data;\n\t}\n\n\tel.innerHTML = data;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/setdatainelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/editor/standardeditor\n */\n\nimport Editor from './editor';\nimport EditingKeystrokeHandler from '../editingkeystrokehandler';\nimport EditingController from '@ckeditor/ckeditor5-engine/src/controller/editingcontroller';\nimport isFunction from '@ckeditor/ckeditor5-utils/src/lib/lodash/isFunction';\n\nimport getDataFromElement from '@ckeditor/ckeditor5-utils/src/dom/getdatafromelement';\nimport setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement';\n\n/**\n * Class representing a typical browser-based editor. It handles a single source element and\n * uses {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @extends module:core/editor/editor~Editor\n */\nexport default class StandardEditor extends Editor {\n\t/**\n\t * Creates a new instance of the standard editor.\n\t *\n\t * @param {HTMLElement} element The DOM element that will be the source\n\t * for the created editor.\n\t * @param {Object} config The editor config.\n\t */\n\tconstructor( element, config ) {\n\t\tsuper( config );\n\n\t\t/**\n\t\t * The element on which the editor has been initialized.\n\t\t *\n\t\t * @readonly\n\t\t * @member {HTMLElement}\n\t\t */\n\t\tthis.element = element;\n\n\t\t// Documented in Editor.\n\t\tthis.editing = new EditingController( this.document );\n\t\tthis.editing.view.bind( 'isReadOnly' ).to( this );\n\n\t\t/**\n\t\t * Instance of the {@link module:core/editingkeystrokehandler~EditingKeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editingkeystrokehandler~EditingKeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new EditingKeystrokeHandler( this );\n\n\t\t/**\n\t\t * Editor UI instance.\n\t\t *\n\t\t * This property is set by more specialized editor constructors. However, it's required\n\t\t * for plugins to work (their UI-related part will try to interact with editor UI),\n\t\t * so every editor class which is meant to work with default plugins should set this property.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editorui~EditorUI} #ui\n\t\t */\n\n\t\tthis.keystrokes.listenTo( this.editing.view );\n\n\t\tthis._attachToForm();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\treturn Promise.resolve()\n\t\t\t.then( () => this.keystrokes.destroy() )\n\t\t\t.then( () => this.editing.destroy() )\n\t\t\t.then( super.destroy() );\n\t}\n\n\t/**\n\t * Sets the data in the editor's main root.\n\t *\n\t * @param {*} data The data to load.\n\t */\n\tsetData( data ) {\n\t\tthis.data.set( data );\n\t}\n\n\t/**\n\t * Gets the data from the editor's main root.\n\t */\n\tgetData() {\n\t\treturn this.data.get();\n\t}\n\n\t/**\n\t * Updates the {@link #element editor element}'s content with the data.\n\t */\n\tupdateEditorElement() {\n\t\tsetDataInElement( this.element, this.getData() );\n\t}\n\n\t/**\n\t * Loads the data from the {@link #element editor element} to the main root.\n\t */\n\tloadDataFromEditorElement() {\n\t\tthis.setData( getDataFromElement( this.element ) );\n\t}\n\n\t/**\n\t * Checks if editor is initialized on textarea element that belongs to a form. If yes - updates editor's element\n\t * contents before submitting the form.\n\t *\n\t * @private\n\t */\n\t_attachToForm() {\n\t\tconst element = this.element;\n\n\t\t// Only when replacing a textarea which is inside of a form element.\n\t\tif ( element && element.tagName.toLowerCase() === 'textarea' && element.form ) {\n\t\t\tlet originalSubmit;\n\t\t\tconst form = element.form;\n\t\t\tconst onSubmit = () => this.updateEditorElement();\n\n\t\t\t// Replace the original form#submit() to call a custom submit function first.\n\t\t\t// Check if #submit is a function because the form might have an input named \"submit\".\n\t\t\tif ( isFunction( form.submit ) ) {\n\t\t\t\toriginalSubmit = form.submit;\n\n\t\t\t\tform.submit = () => {\n\t\t\t\t\tonSubmit();\n\t\t\t\t\toriginalSubmit.apply( form );\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Update the replaced textarea with data before each form#submit event.\n\t\t\tform.addEventListener( 'submit', onSubmit );\n\n\t\t\t// Remove the submit listener and revert the original submit method on\n\t\t\t// editor#destroy.\n\t\t\tthis.on( 'destroy', () => {\n\t\t\t\tform.removeEventListener( 'submit', onSubmit );\n\n\t\t\t\tif ( originalSubmit ) {\n\t\t\t\t\tform.submit = originalSubmit;\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a standard editor instance.\n\t *\n\t * @param {HTMLElement} element See {@link module:core/editor/standardeditor~StandardEditor}'s param.\n\t * @param {Object} config The editor config. You can find the list of config options in\n\t * {@link module:core/editor/editorconfig~EditorConfig}.\n\t * @returns {Promise} Promise resolved once editor is ready.\n\t * @returns {module:core/editor/standardeditor~StandardEditor} return.editor The editor instance.\n\t */\n\tstatic create( element, config ) {\n\t\treturn new Promise( resolve => {\n\t\t\tconst editor = new this( element, config );\n\n\t\t\tresolve(\n\t\t\t\teditor.initPlugins()\n\t\t\t\t\t.then( () => {\n\t\t\t\t\t\teditor.fire( 'dataReady' );\n\t\t\t\t\t\teditor.fire( 'ready' );\n\t\t\t\t\t} )\n\t\t\t\t\t.then( () => editor )\n\t\t\t);\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/src/editor/standardeditor.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/viewcollection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Collects {@link module:ui/view~View} instances.\n *\n *\t\tconst parentView = new ParentView( locale );\n *\t\tconst collection = new ViewCollection( locale );\n *\n *\t\tcollection.setParent( parentView.element );\n *\n *\t\tconst viewA = new ChildView( locale );\n *\t\tconst viewB = new ChildView( locale );\n *\n * View collection renders and manages view {@link module:ui/view~View#element elements}:\n *\n *\t\tcollection.add( viewA );\n *\t\tcollection.add( viewB );\n *\n *\t\tconsole.log( parentView.element.firsChild ); // -> viewA.element\n *\t\tconsole.log( parentView.element.lastChild ); // -> viewB.element\n *\n * It {@link module:ui/viewcollection~ViewCollection#delegate propagates} DOM events too:\n *\n *\t\t// Delegate #click and #keydown events from viewA and viewB to the parentView.\n *\t\tcollection.delegate( 'click' ).to( parentView );\n *\n *\t\tparentView.on( 'click', ( evt ) => {\n *\t\t\tconsole.log( `${ evt.source } has been clicked.` );\n *\t\t} );\n *\n *\t\t// This event will be delegated to the parentView.\n *\t\tviewB.fire( 'click' );\n *\n * **Note**: A view collection can be used directly in the {@link module:ui/template~TemplateDefinition definition}\n * of a {@link module:ui/template~Template template}.\n *\n * @extends module:utils/collection~Collection\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class ViewCollection extends Collection {\n\t/**\n\t * Creates a new instance of the {@link module:ui/viewcollection~ViewCollection}.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The {@link module:core/editor~Editor editor's locale} instance.\n\t */\n\tconstructor( locale ) {\n\t\tsuper( {\n\t\t\t// An #id Number attribute should be legal and not break the `ViewCollection` instance.\n\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/93\n\t\t\tidProperty: 'viewUid'\n\t\t} );\n\n\t\t// Handle {@link module:ui/view~View#element} in DOM when a new view is added to the collection.\n\t\tthis.on( 'add', ( evt, view, index ) => {\n\t\t\tif ( !view.isRendered ) {\n\t\t\t\tview.render();\n\t\t\t}\n\n\t\t\tif ( view.element && this._parentElement ) {\n\t\t\t\tthis._parentElement.insertBefore( view.element, this._parentElement.children[ index ] );\n\t\t\t}\n\t\t} );\n\n\t\t// Handle {@link module:ui/view~View#element} in DOM when a view is removed from the collection.\n\t\tthis.on( 'remove', ( evt, view ) => {\n\t\t\tif ( view.element && this._parentElement ) {\n\t\t\t\tview.element.remove();\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * The {@link module:core/editor/editor~Editor#locale editor's locale} instance.\n\t\t * See the view {@link module:ui/view~View#locale locale} property.\n\t\t *\n\t\t * @member {module:utils/locale~Locale}\n\t\t */\n\t\tthis.locale = locale;\n\n\t\t/**\n\t\t * A parent element within which child views are rendered and managed in DOM.\n\t\t *\n\t\t * @protected\n\t\t * @member {HTMLElement}\n\t\t */\n\t\tthis._parentElement = null;\n\t}\n\n\t/**\n\t * Destroys the view collection along with child views.\n\t * See the view {@link module:ui/view~View#destroy} method.\n\t */\n\tdestroy() {\n\t\tthis.map( view => view.destroy() );\n\t}\n\n\t/**\n\t * Sets the parent HTML element of this collection. When parent is set, {@link #add adding} and\n\t * {@link #remove removing} views in the collection synchronizes their\n\t * {@link module:ui/view~View#element elements} in the parent element.\n\t *\n\t * @param {HTMLElement} element A new parent element.\n\t */\n\tsetParent( elementOrDocFragment ) {\n\t\tthis._parentElement = elementOrDocFragment;\n\t}\n\n\t/**\n\t * Delegates selected events coming from within views in the collection to any\n\t * {@link module:utils/emittermixin~Emitter}.\n\t *\n\t * For the following views and collection:\n\t *\n\t *\t\tconst viewA = new View();\n\t *\t\tconst viewB = new View();\n\t *\t\tconst viewC = new View();\n\t *\n\t *\t\tconst views = parentView.createCollection();\n\t *\n\t *\t\tviews.delegate( 'eventX' ).to( viewB );\n\t *\t\tviews.delegate( 'eventX', 'eventY' ).to( viewC );\n\t *\n\t *\t\tviews.add( viewA );\n\t *\n\t * the `eventX` is delegated (fired by) `viewB` and `viewC` along with `customData`:\n\t *\n\t *\t\tviewA.fire( 'eventX', customData );\n\t *\n\t * and `eventY` is delegated (fired by) `viewC` along with `customData`:\n\t *\n\t *\t\tviewA.fire( 'eventY', customData );\n\t *\n\t * See {@link module:utils/emittermixin~EmitterMixin#delegate}.\n\t *\n\t * @param {...String} events {@link module:ui/view~View} event names to be delegated to another\n\t * {@link module:utils/emittermixin~Emitter}.\n\t * @returns {Object}\n\t * @returns {Function} return.to A function which accepts the destination of\n\t * {@link module:utils/emittermixin~EmitterMixin#delegate delegated} events.\n\t */\n\tdelegate( ...events ) {\n\t\tif ( !events.length || !isStringArray( events ) ) {\n\t\t\t/**\n\t\t\t * All event names must be strings.\n\t\t\t *\n\t\t\t * @error ui-viewcollection-delegate-wrong-events\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'ui-viewcollection-delegate-wrong-events: All event names must be strings.' );\n\t\t}\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * Selects destination for {@link module:utils/emittermixin~EmitterMixin#delegate} events.\n\t\t\t *\n\t\t\t * @memberOf module:ui/viewcollection~ViewCollection#delegate\n\t\t\t * @function module:ui/viewcollection~ViewCollection#delegate.to\n\t\t\t * @param {module:utils/emittermixin~EmitterMixin} dest An `EmitterMixin` instance which is\n\t\t\t * the destination for delegated events.\n\t\t\t */\n\t\t\tto: dest => {\n\t\t\t\t// Activate delegating on existing views in this collection.\n\t\t\t\tfor ( const view of this ) {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.delegate( evtName ).to( dest );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Activate delegating on future views in this collection.\n\t\t\t\tthis.on( 'add', ( evt, view ) => {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.delegate( evtName ).to( dest );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\t// Deactivate delegating when view is removed from this collection.\n\t\t\t\tthis.on( 'remove', ( evt, view ) => {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.stopDelegating( evtName, dest );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Removes a child view from the collection. If the {@link #setParent parent element} of the\n\t * collection has been set, the {@link module:ui/view~View#element element} of the view is also removed\n\t * in DOM, reflecting the order of the collection.\n\t *\n\t * See the {@link #add} method.\n\t *\n\t * @method #remove\n\t * @param {module:ui/view~View|Number|String} subject The view to remove, its id or index in the collection.\n\t * @returns {Object} The removed view.\n\t */\n}\n\nmix( Collection, ObservableMixin );\n\n// Check if all entries of the array are of `String` type.\n//\n// @private\n// @param {Array} arr An array to be checked.\n// @returns {Boolean}\nfunction isStringArray( arr ) {\n\treturn arr.every( a => typeof a == 'string' );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/viewcollection.js\n// module id = null\n// module chunks = ","import baseClone from './_baseClone';\n\n/**\n * This method is like `_.cloneWith` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the deep cloned value.\n * @see _.cloneWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(true);\n * }\n * }\n *\n * var el = _.cloneDeepWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 20\n */\nfunction cloneDeepWith(value, customizer) {\n return baseClone(value, true, true, customizer);\n}\n\nexport default cloneDeepWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/cloneDeepWith.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/template\n */\n\n/* global document */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport View from './view';\nimport ViewCollection from './viewcollection';\nimport cloneDeepWith from '@ckeditor/ckeditor5-utils/src/lib/lodash/cloneDeepWith';\nimport isObject from '@ckeditor/ckeditor5-utils/src/lib/lodash/isObject';\nimport isDomNode from '@ckeditor/ckeditor5-utils/src/dom/isdomnode';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\nconst xhtmlNs = 'http://www.w3.org/1999/xhtml';\n\n/**\n * A basic Template class. It renders a DOM HTML element or text from a\n * {@link module:ui/template~TemplateDefinition definition} and supports element attributes, children,\n * bindings to {@link module:utils/observablemixin~Observable observables} and DOM event propagation.\n *\n * A simple template can look like this:\n *\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\tattributes: {\n *\t\t\t\tclass: 'foo',\n *\t\t\t\tstyle: {\n *\t\t\t\t\tbackgroundColor: 'yellow'\n *\t\t\t\t}\n *\t\t\t},\n *\t\t\ton: {\n *\t\t\t\tclick: bind.to( 'clicked' )\n *\t\t\t}\n *\t\t\tchildren: [\n *\t\t\t\t'A paragraph.'\n *\t\t\t]\n *\t\t} ).render();\n *\n * and it will render the following HTML element:\n *\n *\t\t<p class=\"foo\" style=\"background-color: yellow;\">A paragraph.</p>\n *\n * Additionally, the `observable` will always fire `clicked` upon clicking `<p>` in the DOM.\n *\n * See {@link module:ui/template~TemplateDefinition} to know more about templates and complex\n * template definitions.\n *\n* @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class Template {\n\t/**\n\t * Creates an instance of the {@link ~Template} class.\n\t *\n\t * @param {module:ui/template~TemplateDefinition} def The definition of the template.\n\t */\n\tconstructor( def ) {\n\t\tObject.assign( this, normalize( clone( def ) ) );\n\n\t\t/**\n\t\t * Indicates whether this particular Template instance has been\n\t\t * {@link #render rendered}.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._isRendered = false;\n\n\t\t/**\n\t\t * The tag (`tagName`) of this template, e.g. `div`. It also indicates that the template\n\t\t * renders to an HTML element.\n\t\t *\n\t\t * @member {String} #tag\n\t\t */\n\n\t\t/**\n\t\t * The text of the template. It also indicates that the template renders to a DOM text node.\n\t\t *\n\t\t * @member {Array.<String|module:ui/template~TemplateValueSchema>} #text\n\t\t */\n\n\t\t/**\n\t\t * The attributes of the template, e.g. `{ id: [ 'ck-id' ] }`, corresponding with\n\t\t * the attributes of an HTML element.\n\t\t *\n\t\t * **Note**: This property only makes sense when {@link #tag} is defined.\n\t\t *\n\t\t * @member {Object} #attributes\n\t\t */\n\n\t\t/**\n\t\t * The children of the template. They can be either:\n\t\t * * independent instances of {@link ~Template} (subtemplates),\n\t\t * * native DOM Nodes.\n\t\t *\n\t\t * **Note**: This property only makes sense when {@link #tag} is defined.\n\t\t *\n\t\t * @member {Array.<module:ui/template~Template|Node>} #children\n\t\t */\n\n\t\t/**\n\t\t * The DOM event listeners of the template.\n\t\t *\n\t\t * @member {Object} #eventListeners\n\t\t */\n\n\t\t/**\n\t\t * The data used by the {@link #revert} method to restore a node to its original state.\n\t\t *\n\t\t * See: {@link #apply}.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/template~RenderData}\n\t\t */\n\t\tthis._revertData = null;\n\t}\n\n\t/**\n\t * Renders a DOM Node (an HTML element or text) out of the template.\n\t *\n\t *\t\tconst domNode = new Template( { ... } ).render();\n\t *\n\t * See: {@link #apply}.\n\t *\n\t * @returns {HTMLElement|Text}\n\t */\n\trender() {\n\t\tconst node = this._renderNode( {\n\t\t\tintoFragment: true\n\t\t} );\n\n\t\tthis._isRendered = true;\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Applies the template to an existing DOM Node, either HTML element or text.\n\t *\n\t * **Note:** No new DOM nodes will be created. Applying extends\n\t * {@link module:ui/template~TemplateDefinition attributes} and\n\t * {@link module:ui/template~TemplateDefinition event listeners} only.\n\t *\n\t * **Note:** Existing `class` and `style` attributes are extended when a template\n\t * is applied to an HTML element, while other attributes and `textContent` are overridden.\n\t *\n\t * **Note:** The process of applying a template can be easily reverted using the\n\t * {@link module:ui/template~Template#revert} method.\n\t *\n\t *\t\tconst element = document.createElement( 'div' );\n\t *\t\tconst bind = Template.bind( observable, emitter );\n\t *\n\t *\t\tnew Template( {\n\t *\t\t\tattrs: {\n\t *\t\t\t\tid: 'first-div',\n\t *\t\t\t\tclass: bind.to( 'divClass' )\n\t *\t\t\t},\n\t *\t\t\ton: {\n\t *\t\t\t\tclick: bind( 'elementClicked' ) // Will be fired by the observable.\n\t *\t\t\t}\n\t *\t\t\tchildren: [\n\t *\t\t\t\t'Div text.'\n\t *\t\t\t]\n\t *\t\t} ).apply( element );\n\t *\n\t *\t\telement.outerHTML == \"<div id=\"first-div\" class=\"my-div\">Div text.</div>\"\n\t *\n\t * @see module:ui/template~Template#render\n\t * @see module:ui/template~Template#revert\n\t * @param {Node} node Root node for the template to apply.\n\t */\n\tapply( node ) {\n\t\tthis._revertData = getEmptyRevertData();\n\n\t\tthis._renderNode( {\n\t\t\tnode,\n\t\t\tisApplying: true,\n\t\t\trevertData: this._revertData\n\t\t} );\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Reverts a template {@link module:ui/template~Template#apply applied} to a DOM node.\n\t *\n\t * @param {Node} node The root node for the template to revert. In most of the cases, it is the\n\t * same node used by {@link module:ui/template~Template#apply}.\n\t */\n\trevert( node ) {\n\t\tif ( !this._revertData ) {\n\t\t\t/**\n\t\t\t * Attempting to revert a template which has not been applied yet.\n\t\t\t *\n\t\t\t * @error ui-template-revert-not-applied\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'ui-template-revert-not-applied: Attempting to revert a template which has not been applied yet.' );\n\t\t}\n\n\t\tthis._revertTemplateFromNode( node, this._revertData );\n\t}\n\n\t/**\n\t * Returns an iterator which traverses the template in search of {@link module:ui/view~View}\n\t * instances and returns them one by one.\n\t *\n\t *\t\tconst viewFoo = new View();\n\t *\t\tconst viewBar = new View();\n\t *\t\tconst viewBaz = new View();\n\t *\t\tconst template = new Template( {\n\t *\t\t\ttag: 'div',\n\t *\t\t\tchildren: [\n\t *\t\t\t\tviewFoo,\n\t *\t\t\t\t{\n\t *\t\t\t\t\ttag: 'div',\n\t *\t\t\t\t\tchildren: [\n\t *\t\t\t\t\t\tviewBar\n\t *\t\t\t\t\t]\n\t *\t\t\t\t},\n\t *\t\t\t\tviewBaz\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t *\t\t// Logs: viewFoo, viewBar, viewBaz\n\t *\t\tfor ( const view of template.getViews() ) {\n\t *\t\t\tconsole.log( view );\n\t *\t\t}\n\t *\n\t * @returns {Iterator.<module:ui/view~View>}\n\t */\n\t* getViews() {\n\t\tfunction* search( def ) {\n\t\t\tif ( def.children ) {\n\t\t\t\tfor ( const child of def.children ) {\n\t\t\t\t\tif ( isView( child ) ) {\n\t\t\t\t\t\tyield child;\n\t\t\t\t\t} else if ( isTemplate( child ) ) {\n\t\t\t\t\t\tyield* search( child );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tyield* search( this );\n\t}\n\n\t/**\n\t * An entry point to the interface which binds DOM nodes to\n\t * {@link module:utils/observablemixin~Observable observables}.\n\t * There are two types of bindings:\n\t *\n\t * * HTML element attributes or text `textContent` synchronized with attributes of an\n\t * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}\n\t * and {@link module:ui/template~BindChain#if}.\n\t *\n\t *\t\tconst bind = Template.bind( observable, emitter );\n\t *\n\t *\t\tnew Template( {\n\t *\t\t\tattrs: {\n\t *\t\t\t\t// Binds the element \"class\" attribute to observable#classAttribute.\n\t *\t\t\t\tclass: bind.to( 'classAttribute' )\n\t *\t\t\t}\n\t *\t\t} ).render();\n\t *\n\t * * DOM events fired on HTML element propagated through\n\t * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}.\n\t *\n\t *\t\tconst bind = Template.bind( observable, emitter );\n\t *\n\t *\t\tnew Template( {\n\t *\t\t\ton: {\n\t *\t\t\t\t// Will be fired by the observable.\n\t *\t\t\t\tclick: bind( 'elementClicked' )\n\t *\t\t\t}\n\t *\t\t} ).render();\n\t *\n\t * Also see {@link module:ui/view~View#bindTemplate}.\n\t *\n\t * @param {module:utils/observablemixin~Observable} observable An observable which provides boundable attributes.\n\t * @param {module:utils/emittermixin~Emitter} emitter An emitter that listens to observable attribute\n\t * changes or DOM Events (depending on the kind of the binding). Usually, a {@link module:ui/view~View} instance.\n\t * @returns {module:ui/template~BindChain}\n\t */\n\tstatic bind( observable, emitter ) {\n\t\treturn {\n\t\t\tto( eventNameOrFunctionOrAttribute, callback ) {\n\t\t\t\treturn new TemplateToBinding( {\n\t\t\t\t\teventNameOrFunction: eventNameOrFunctionOrAttribute,\n\t\t\t\t\tattribute: eventNameOrFunctionOrAttribute,\n\t\t\t\t\tobservable, emitter, callback\n\t\t\t\t} );\n\t\t\t},\n\n\t\t\tif( attribute, valueIfTrue, callback ) {\n\t\t\t\treturn new TemplateIfBinding( {\n\t\t\t\t\tobservable, emitter, attribute, valueIfTrue, callback\n\t\t\t\t} );\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Extends an existing {@link module:ui/template~Template} instance with some additional content\n\t * from another {@link module:ui/template~TemplateDefinition}.\n\t *\n\t *\t\tconst bind = Template.bind( observable, emitter );\n\t *\n\t *\t\tconst template = new Template( {\n\t *\t\t\ttag: 'p',\n\t *\t\t\tattributes: {\n\t *\t\t\t\tclass: 'a',\n\t *\t\t\t\tdata-x: bind.to( 'foo' )\n\t *\t\t\t},\n\t *\t\t\tchildren: [\n\t *\t\t\t\t{\n\t *\t\t\t\t\ttag: 'span',\n\t *\t\t\t\t\tattributes: {\n\t *\t\t\t\t\t\tclass: 'b'\n\t *\t\t\t\t\t},\n\t *\t\t\t\t\tchildren: [\n\t *\t\t\t\t\t\t'Span'\n\t *\t\t\t\t\t]\n\t *\t\t\t\t}\n\t *\t\t\t]\n\t *\t\t } );\n\t *\n\t *\t\t// Instance-level extension.\n\t *\t\tTemplate.extend( template, {\n\t *\t\t\tattributes: {\n\t *\t\t\t\tclass: 'b',\n\t *\t\t\t\tdata-x: bind.to( 'bar' )\n\t *\t\t\t},\n\t *\t\t\tchildren: [\n\t *\t\t\t\t{\n\t *\t\t\t\t\tattributes: {\n\t *\t\t\t\t\t\tclass: 'c'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t *\t\t// Child extension.\n\t *\t\tTemplate.extend( template.children[ 0 ], {\n\t *\t\t\tattributes: {\n\t *\t\t\t\tclass: 'd'\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * the `outerHTML` of `template.render()` is:\n\t *\n\t *\t\t<p class=\"a b\" data-x=\"{ observable.foo } { observable.bar }\">\n\t *\t\t\t<span class=\"b c d\">Span</span>\n\t *\t\t</p>\n\t *\n\t * @param {module:ui/template~Template} template An existing template instance to be extended.\n\t * @param {module:ui/template~TemplateDefinition} def Additional definition to be applied to a template.\n\t */\n\tstatic extend( template, def ) {\n\t\tif ( template._isRendered ) {\n\t\t\t/**\n\t\t\t * Extending a template after rendering may not work as expected. To make sure\n\t\t\t * the {@link module:ui/template~Template.extend extending} works for an element,\n\t\t\t * make sure it happens before {@link #render} is called.\n\t\t\t *\n\t\t\t * @error template-extend-render\n\t\t\t */\n\t\t\tlog.warn( 'template-extend-render: Attempting to extend a template which has already been rendered.' );\n\t\t}\n\n\t\textendTemplate( template, normalize( clone( def ) ) );\n\t}\n\n\t/**\n\t * Renders a DOM Node (either an HTML element or text) out of the template.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderNode( data ) {\n\t\tlet isInvalid;\n\n\t\tif ( data.node ) {\n\t\t\t// When applying, a definition cannot have \"tag\" and \"text\" at the same time.\n\t\t\tisInvalid = this.tag && this.text;\n\t\t} else {\n\t\t\t// When rendering, a definition must have either \"tag\" or \"text\": XOR( this.tag, this.text ).\n\t\t\tisInvalid = this.tag ? this.text : !this.text;\n\t\t}\n\n\t\tif ( isInvalid ) {\n\t\t\t/**\n\t\t\t * Node definition cannot have the \"tag\" and \"text\" properties at the same time.\n\t\t\t * Node definition must have either \"tag\" or \"text\" when rendering a new Node.\n\t\t\t *\n\t\t\t * @error ui-template-wrong-syntax\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'ui-template-wrong-syntax: Node definition must have either \"tag\" or \"text\" when rendering a new Node.'\n\t\t\t);\n\t\t}\n\n\t\tif ( this.text ) {\n\t\t\treturn this._renderText( data );\n\t\t} else {\n\t\t\treturn this._renderElement( data );\n\t\t}\n\t}\n\n\t/**\n\t * Renders an HTML element out of the template.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderElement( data ) {\n\t\tlet node = data.node;\n\n\t\tif ( !node ) {\n\t\t\tnode = data.node = document.createElementNS( this.ns || xhtmlNs, this.tag );\n\t\t}\n\n\t\tthis._renderAttributes( data );\n\t\tthis._renderElementChildren( data );\n\t\tthis._setUpListeners( data );\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Renders a text node out of {@link module:ui/template~Template#text}.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderText( data ) {\n\t\tlet node = data.node;\n\n\t\t// Save the original textContent to revert it in #revert().\n\t\tif ( node ) {\n\t\t\tdata.revertData.text = node.textContent;\n\t\t} else {\n\t\t\tnode = data.node = document.createTextNode( '' );\n\t\t}\n\n\t\t// Check if this Text Node is bound to Observable. Cases:\n\t\t//\n\t\t//\t\ttext: [ Template.bind( ... ).to( ... ) ]\n\t\t//\n\t\t//\t\ttext: [\n\t\t//\t\t\t'foo',\n\t\t//\t\t\tTemplate.bind( ... ).to( ... ),\n\t\t//\t\t\t...\n\t\t//\t\t]\n\t\t//\n\t\tif ( hasTemplateBinding( this.text ) ) {\n\t\t\tthis._bindToObservable( {\n\t\t\t\tschema: this.text,\n\t\t\t\tupdater: getTextUpdater( node ),\n\t\t\t\tdata\n\t\t\t} );\n\t\t}\n\t\t// Simply set text. Cases:\n\t\t//\n\t\t//\t\ttext: [ 'all', 'are', 'static' ]\n\t\t//\n\t\t//\t\ttext: [ 'foo' ]\n\t\t//\n\t\telse {\n\t\t\tnode.textContent = this.text.join( '' );\n\t\t}\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Renders HTML element attributes out of {@link module:ui/template~Template#attributes}.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderAttributes( data ) {\n\t\tlet attrName, attrValue, domAttrValue, attrNs;\n\n\t\tif ( !this.attributes ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst node = data.node;\n\t\tconst revertData = data.revertData;\n\n\t\tfor ( attrName in this.attributes ) {\n\t\t\t// Current attribute value in DOM.\n\t\t\tdomAttrValue = node.getAttribute( attrName );\n\n\t\t\t// The value to be set.\n\t\t\tattrValue = this.attributes[ attrName ];\n\n\t\t\t// Save revert data.\n\t\t\tif ( revertData ) {\n\t\t\t\trevertData.attributes[ attrName ] = domAttrValue;\n\t\t\t}\n\n\t\t\t// Detect custom namespace:\n\t\t\t//\n\t\t\t//\t\tclass: {\n\t\t\t//\t\t\tns: 'abc',\n\t\t\t//\t\t\tvalue: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tattrNs = ( isObject( attrValue[ 0 ] ) && attrValue[ 0 ].ns ) ? attrValue[ 0 ].ns : null;\n\n\t\t\t// Activate binding if one is found. Cases:\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\tTemplate.bind( ... ).to( ... )\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t'bar',\n\t\t\t//\t\t\tTemplate.bind( ... ).to( ... ),\n\t\t\t//\t\t\t'baz'\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\t//\t\tclass: {\n\t\t\t//\t\t\tns: 'abc',\n\t\t\t//\t\t\tvalue: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tif ( hasTemplateBinding( attrValue ) ) {\n\t\t\t\t// Normalize attributes with additional data like namespace:\n\t\t\t\t//\n\t\t\t\t//\t\tclass: {\n\t\t\t\t//\t\t\tns: 'abc',\n\t\t\t\t//\t\t\tvalue: [ ... ]\n\t\t\t\t//\t\t}\n\t\t\t\t//\n\t\t\t\tconst valueToBind = attrNs ? attrValue[ 0 ].value : attrValue;\n\n\t\t\t\t// Extend the original value of attributes like \"style\" and \"class\",\n\t\t\t\t// don't override them.\n\t\t\t\tif ( revertData && shouldExtend( attrName ) ) {\n\t\t\t\t\tvalueToBind.unshift( domAttrValue );\n\t\t\t\t}\n\n\t\t\t\tthis._bindToObservable( {\n\t\t\t\t\tschema: valueToBind,\n\t\t\t\t\tupdater: getAttributeUpdater( node, attrName, attrNs ),\n\t\t\t\t\tdata\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Style attribute could be an Object so it needs to be parsed in a specific way.\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\twidth: '100px',\n\t\t\t//\t\t\theight: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\telse if ( attrName == 'style' && typeof attrValue[ 0 ] !== 'string' ) {\n\t\t\t\tthis._renderStyleAttribute( attrValue[ 0 ], data );\n\t\t\t}\n\n\t\t\t// Otherwise simply set the static attribute:\n\t\t\t//\n\t\t\t//\t\tclass: [ 'foo' ]\n\t\t\t//\n\t\t\t//\t\tclass: [ 'all', 'are', 'static' ]\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t{\n\t\t\t//\t\t\t\tns: 'abc',\n\t\t\t//\t\t\t\tvalue: [ 'foo' ]\n\t\t\t//\t\t\t}\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\telse {\n\t\t\t\t// Extend the original value of attributes like \"style\" and \"class\",\n\t\t\t\t// don't override them.\n\t\t\t\tif ( revertData && domAttrValue && shouldExtend( attrName ) ) {\n\t\t\t\t\tattrValue.unshift( domAttrValue );\n\t\t\t\t}\n\n\t\t\t\tattrValue = attrValue\n\t\t\t\t\t// Retrieve \"values\" from:\n\t\t\t\t\t//\n\t\t\t\t\t//\t\tclass: [\n\t\t\t\t\t//\t\t\t{\n\t\t\t\t\t//\t\t\t\tns: 'abc',\n\t\t\t\t\t//\t\t\t\tvalue: [ ... ]\n\t\t\t\t\t//\t\t\t}\n\t\t\t\t\t//\t\t]\n\t\t\t\t\t//\n\t\t\t\t\t.map( val => val ? ( val.value || val ) : val )\n\t\t\t\t\t// Flatten the array.\n\t\t\t\t\t.reduce( ( prev, next ) => prev.concat( next ), [] )\n\t\t\t\t\t// Convert into string.\n\t\t\t\t\t.reduce( arrayValueReducer, '' );\n\n\t\t\t\tif ( !isFalsy( attrValue ) ) {\n\t\t\t\t\tnode.setAttributeNS( attrNs, attrName, attrValue );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Renders the `style` attribute of an HTML element based on\n\t * {@link module:ui/template~Template#attributes}.\n\t *\n\t * A style attribute is an {Object} with static values:\n\t *\n\t *\t\tattributes: {\n\t *\t\t\tstyle: {\n\t *\t\t\t\tcolor: 'red'\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t * or values bound to {@link module:ui/model~Model} properties:\n\t *\n\t *\t\tattributes: {\n\t *\t\t\tstyle: {\n\t *\t\t\t\tcolor: bind.to( ... )\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t * Note: The `style` attribute is rendered without setting the namespace. It does not seem to be\n\t * needed.\n\t *\n\t * @private\n\t * @param {Object} styles Styles located in `attributes.style` of {@link module:ui/template~TemplateDefinition}.\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderStyleAttribute( styles, data ) {\n\t\tconst node = data.node;\n\n\t\tfor ( const styleName in styles ) {\n\t\t\tconst styleValue = styles[ styleName ];\n\n\t\t\t// Cases:\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\tcolor: bind.to( 'attribute' )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tif ( hasTemplateBinding( styleValue ) ) {\n\t\t\t\tthis._bindToObservable( {\n\t\t\t\t\tschema: [ styleValue ],\n\t\t\t\t\tupdater: getStyleUpdater( node, styleName ),\n\t\t\t\t\tdata\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Cases:\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\tcolor: 'red'\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\telse {\n\t\t\t\tnode.style[ styleName ] = styleValue;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Recursively renders HTML element's children from {@link module:ui/template~Template#children}.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderElementChildren( data ) {\n\t\tconst node = data.node;\n\t\tconst container = data.intoFragment ? document.createDocumentFragment() : node;\n\t\tconst isApplying = data.isApplying;\n\t\tlet childIndex = 0;\n\n\t\tfor ( const child of this.children ) {\n\t\t\tif ( isViewCollection( child ) ) {\n\t\t\t\tif ( !isApplying ) {\n\t\t\t\t\tchild.setParent( node );\n\n\t\t\t\t\t// Note: ViewCollection renders its children.\n\t\t\t\t\tfor ( const view of child ) {\n\t\t\t\t\t\tcontainer.appendChild( view.element );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ( isView( child ) ) {\n\t\t\t\tif ( !isApplying ) {\n\t\t\t\t\tif ( !child.isRendered ) {\n\t\t\t\t\t\tchild.render();\n\t\t\t\t\t}\n\n\t\t\t\t\tcontainer.appendChild( child.element );\n\t\t\t\t}\n\t\t\t} else if ( isDomNode( child ) ) {\n\t\t\t\tcontainer.appendChild( child );\n\t\t\t} else {\n\t\t\t\tif ( isApplying ) {\n\t\t\t\t\tconst revertData = data.revertData;\n\t\t\t\t\tconst childRevertData = getEmptyRevertData();\n\n\t\t\t\t\trevertData.children.push( childRevertData );\n\n\t\t\t\t\tchild._renderNode( {\n\t\t\t\t\t\tnode: container.childNodes[ childIndex++ ],\n\t\t\t\t\t\tisApplying: true,\n\t\t\t\t\t\trevertData: childRevertData\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\tcontainer.appendChild( child.render() );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( data.intoFragment ) {\n\t\t\tnode.appendChild( container );\n\t\t}\n\t}\n\n\t/**\n\t * Activates `on` event listeners from the {@link module:ui/template~TemplateDefinition}\n\t * on an HTML element.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_setUpListeners( data ) {\n\t\tif ( !this.eventListeners ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const key in this.eventListeners ) {\n\t\t\tconst revertBindings = this.eventListeners[ key ].map( schemaItem => {\n\t\t\t\tconst [ domEvtName, domSelector ] = key.split( '@' );\n\n\t\t\t\treturn schemaItem.activateDomEventListener( domEvtName, domSelector, data );\n\t\t\t} );\n\n\t\t\tif ( data.revertData ) {\n\t\t\t\tdata.revertData.bindings.push( revertBindings );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * For a given {@link module:ui/template~TemplateValueSchema} containing {@link module:ui/template~TemplateBinding}\n\t * activates the binding and sets its initial value.\n\t *\n\t * Note: {@link module:ui/template~TemplateValueSchema} can be for HTML element attributes or\n\t * text node `textContent`.\n\t *\n\t * @protected\n\t * @param {Object} options Binding options.\n\t * @param {module:ui/template~TemplateValueSchema} options.schema\n\t * @param {Function} options.updater A function which updates the DOM (like attribute or text).\n\t * @param {module:ui/template~RenderData} options.data Rendering data.\n\t */\n\t_bindToObservable( { schema, updater, data } ) {\n\t\tconst revertData = data.revertData;\n\n\t\t// Set initial values.\n\t\tsyncValueSchemaValue( schema, updater, data );\n\n\t\tconst revertBindings = schema\n\t\t\t// Filter \"falsy\" (false, undefined, null, '') value schema components out.\n\t\t\t.filter( item => !isFalsy( item ) )\n\t\t\t// Filter inactive bindings from schema, like static strings ('foo'), numbers (42), etc.\n\t\t\t.filter( item => item.observable )\n\t\t\t// Once only the actual binding are left, let the emitter listen to observable change:attribute event.\n\t\t\t// TODO: Reduce the number of listeners attached as many bindings may listen\n\t\t\t// to the same observable attribute.\n\t\t\t.map( templateBinding => templateBinding.activateAttributeListener( schema, updater, data ) );\n\n\t\tif ( revertData ) {\n\t\t\trevertData.bindings.push( revertBindings );\n\t\t}\n\t}\n\n\t/**\n\t * Reverts {@link module:ui/template~RenderData#revertData template data} from a node to\n\t * return it to the original state.\n\t *\n\t * @protected\n\t * @param {HTMLElement|Text} node A node to be reverted.\n\t * @param {module:ui/template~RenderData#revertData} revertData Stores information about\n\t * what changes have been made by {@link #apply} to the node.\n\t */\n\t_revertTemplateFromNode( node, revertData ) {\n\t\tfor ( const binding of revertData.bindings ) {\n\t\t\t// Each binding may consist of several observable+observable#attribute.\n\t\t\t// like the following has 2:\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t'x',\n\t\t\t//\t\t\tbind.to( 'foo' ),\n\t\t\t//\t\t\t'y',\n\t\t\t//\t\t\tbind.to( 'bar' )\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\tfor ( const revertBinding of binding ) {\n\t\t\t\trevertBinding();\n\t\t\t}\n\t\t}\n\n\t\tif ( revertData.text ) {\n\t\t\tnode.textContent = revertData.text;\n\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const attrName in revertData.attributes ) {\n\t\t\tconst attrValue = revertData.attributes[ attrName ];\n\n\t\t\t// When the attribute has **not** been set before #apply().\n\t\t\tif ( attrValue === null ) {\n\t\t\t\tnode.removeAttribute( attrName );\n\t\t\t} else {\n\t\t\t\tnode.setAttribute( attrName, attrValue );\n\t\t\t}\n\t\t}\n\n\t\tfor ( let i = 0; i < revertData.children.length; ++i ) {\n\t\t\tthis._revertTemplateFromNode( node.childNodes[ i ], revertData.children[ i ] );\n\t\t}\n\t}\n}\n\nmix( Template, EmitterMixin );\n\n/**\n * Describes a binding created by the {@link module:ui/template~Template.bind} interface.\n *\n * @protected\n */\nexport class TemplateBinding {\n\t/**\n\t * Creates an instance of the {@link module:ui/template~TemplateBinding} class.\n\t *\n\t * @param {module:ui/template~TemplateDefinition} def The definition of the binding.\n\t */\n\tconstructor( def ) {\n\t\tObject.assign( this, def );\n\n\t\t/**\n\t\t * An observable instance of the binding. It either:\n\t\t *\n\t\t * * provides the attribute with the value,\n\t\t * * or passes the event when a corresponding DOM event is fired.\n\t\t *\n\t\t * @member {module:utils/observablemixin~ObservableMixin} module:ui/template~TemplateBinding#observable\n\t\t */\n\n\t\t/**\n\t\t * An {@link module:utils/emittermixin~Emitter} used by the binding to:\n\t\t *\n\t\t * * listen to the attribute change in the {@link module:ui/template~TemplateBinding#observable},\n\t\t * * or listen to the event in the DOM.\n\t\t *\n\t\t * @member {module:utils/emittermixin~EmitterMixin} module:ui/template~TemplateBinding#emitter\n\t\t */\n\n\t\t/**\n\t\t * The name of the {@link module:ui/template~TemplateBinding#observable observed attribute}.\n\t\t *\n\t\t * @member {String} module:ui/template~TemplateBinding#attribute\n\t\t */\n\n\t\t/**\n\t\t * A custom function to process the value of the {@link module:ui/template~TemplateBinding#attribute}.\n\t\t *\n\t\t * @member {Function} [module:ui/template~TemplateBinding#callback]\n\t\t */\n\t}\n\n\t/**\n\t * Returns the value of the binding. It is the value of the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}. The value may be processed by the\n\t * {@link module:ui/template~TemplateBinding#callback}, if such has been passed to the binding.\n\t *\n\t * @param {Node} [node] A native DOM node, passed to the custom {@link module:ui/template~TemplateBinding#callback}.\n\t * @returns {*} The value of {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}.\n\t */\n\tgetValue( node ) {\n\t\tconst value = this.observable[ this.attribute ];\n\n\t\treturn this.callback ? this.callback( value, node ) : value;\n\t}\n\n\t/**\n\t * Activates the listener which waits for changes of the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}, then updates the DOM with the aggregated\n\t * value of {@link module:ui/template~TemplateValueSchema}.\n\t *\n\t * @param {module:ui/template~TemplateValueSchema} schema A full schema to generate an attribute or text in the DOM.\n\t * @param {Function} updater A DOM updater function used to update the native DOM attribute or text.\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t * @returns {Function} A function to sever the listener binding.\n\t */\n\tactivateAttributeListener( schema, updater, data ) {\n\t\tconst callback = () => syncValueSchemaValue( schema, updater, data );\n\n\t\tthis.emitter.listenTo( this.observable, 'change:' + this.attribute, callback );\n\n\t\t// Allows revert of the listener.\n\t\treturn () => {\n\t\t\tthis.emitter.stopListening( this.observable, 'change:' + this.attribute, callback );\n\t\t};\n\t}\n}\n\n/**\n * Describes either:\n *\n * * a binding to an {@link module:utils/observablemixin~Observable},\n * * or a native DOM event binding.\n *\n * It is created by the {@link module:ui/template~BindChain#to} method.\n *\n * @protected\n */\nexport class TemplateToBinding extends TemplateBinding {\n\t/**\n\t * Activates the listener for the native DOM event, which when fired, is propagated by\n\t * the {@link module:ui/template~TemplateBinding#emitter}.\n\t *\n\t * @param {String} domEvtName The name of the native DOM event.\n\t * @param {String} domSelector The selector in the DOM to filter delegated events.\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t * @returns {Function} A function to sever the listener binding.\n\t */\n\tactivateDomEventListener( domEvtName, domSelector, data ) {\n\t\tconst callback = ( evt, domEvt ) => {\n\t\t\tif ( !domSelector || domEvt.target.matches( domSelector ) ) {\n\t\t\t\tif ( typeof this.eventNameOrFunction == 'function' ) {\n\t\t\t\t\tthis.eventNameOrFunction( domEvt );\n\t\t\t\t} else {\n\t\t\t\t\tthis.observable.fire( this.eventNameOrFunction, domEvt );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tthis.emitter.listenTo( data.node, domEvtName, callback );\n\n\t\t// Allows revert of the listener.\n\t\treturn () => {\n\t\t\tthis.emitter.stopListening( data.node, domEvtName, callback );\n\t\t};\n\t}\n}\n\n/**\n * Describes a binding to {@link module:utils/observablemixin~ObservableMixin} created by the {@link module:ui/template~BindChain#if}\n * method.\n *\n * @protected\n */\nexport class TemplateIfBinding extends TemplateBinding {\n\t/**\n\t * @inheritDoc\n\t */\n\tgetValue( node ) {\n\t\tconst value = super.getValue( node );\n\n\t\treturn isFalsy( value ) ? false : ( this.valueIfTrue || true );\n\t}\n\n\t/**\n\t * The value of the DOM attribute or text to be set if the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable} is `true`.\n\t *\n\t * @member {String} [module:ui/template~TemplateIfBinding#valueIfTrue]\n\t */\n}\n\n// Checks whether given {@link module:ui/template~TemplateValueSchema} contains a\n// {@link module:ui/template~TemplateBinding}.\n//\n// @param {module:ui/template~TemplateValueSchema} schema\n// @returns {Boolean}\nfunction hasTemplateBinding( schema ) {\n\tif ( !schema ) {\n\t\treturn false;\n\t}\n\n\t// Normalize attributes with additional data like namespace:\n\t//\n\t//\t\tclass: {\n\t//\t\t\tns: 'abc',\n\t//\t\t\tvalue: [ ... ]\n\t//\t\t}\n\t//\n\tif ( schema.value ) {\n\t\tschema = schema.value;\n\t}\n\n\tif ( Array.isArray( schema ) ) {\n\t\treturn schema.some( hasTemplateBinding );\n\t} else if ( schema instanceof TemplateBinding ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n// Assembles the value using {@link module:ui/template~TemplateValueSchema} and stores it in a form of\n// an Array. Each entry of the Array corresponds to one of {@link module:ui/template~TemplateValueSchema}\n// items.\n//\n// @param {module:ui/template~TemplateValueSchema} schema\n// @param {Node} node DOM Node updated when {@link module:utils/observablemixin~ObservableMixin} changes.\n// @return {Array}\nfunction getValueSchemaValue( schema, node ) {\n\treturn schema.map( schemaItem => {\n\t\t// Process {@link module:ui/template~TemplateBinding} bindings.\n\t\tif ( schemaItem instanceof TemplateBinding ) {\n\t\t\treturn schemaItem.getValue( node );\n\t\t}\n\n\t\t// All static values like strings, numbers, and \"falsy\" values (false, null, undefined, '', etc.) just pass.\n\t\treturn schemaItem;\n\t} );\n}\n\n// A function executed each time the bound Observable attribute changes, which updates the DOM with a value\n// constructed from {@link module:ui/template~TemplateValueSchema}.\n//\n// @param {module:ui/template~TemplateValueSchema} schema\n// @param {Function} updater A function which updates the DOM (like attribute or text).\n// @param {Node} node DOM Node updated when {@link module:utils/observablemixin~ObservableMixin} changes.\nfunction syncValueSchemaValue( schema, updater, { node } ) {\n\tlet value = getValueSchemaValue( schema, node );\n\n\t// Check if schema is a single Template.bind.if, like:\n\t//\n\t//\t\tclass: Template.bind.if( 'foo' )\n\t//\n\tif ( schema.length == 1 && schema[ 0 ] instanceof TemplateIfBinding ) {\n\t\tvalue = value[ 0 ];\n\t} else {\n\t\tvalue = value.reduce( arrayValueReducer, '' );\n\t}\n\n\tif ( isFalsy( value ) ) {\n\t\tupdater.remove();\n\t} else {\n\t\tupdater.set( value );\n\t}\n}\n\n// Returns an object consisting of `set` and `remove` functions, which\n// can be used in the context of DOM Node to set or reset `textContent`.\n// @see module:ui/view~View#_bindToObservable\n//\n// @param {Node} node DOM Node to be modified.\n// @returns {Object}\nfunction getTextUpdater( node ) {\n\treturn {\n\t\tset( value ) {\n\t\t\tnode.textContent = value;\n\t\t},\n\n\t\tremove() {\n\t\t\tnode.textContent = '';\n\t\t}\n\t};\n}\n\n// Returns an object consisting of `set` and `remove` functions, which\n// can be used in the context of DOM Node to set or reset an attribute.\n// @see module:ui/view~View#_bindToObservable\n//\n// @param {Node} node DOM Node to be modified.\n// @param {String} attrName Name of the attribute to be modified.\n// @param {String} [ns=null] Namespace to use.\n// @returns {Object}\nfunction getAttributeUpdater( el, attrName, ns ) {\n\treturn {\n\t\tset( value ) {\n\t\t\tel.setAttributeNS( ns, attrName, value );\n\t\t},\n\n\t\tremove() {\n\t\t\tel.removeAttributeNS( ns, attrName );\n\t\t}\n\t};\n}\n\n// Returns an object consisting of `set` and `remove` functions, which\n// can be used in the context of CSSStyleDeclaration to set or remove a style.\n// @see module:ui/view~View#_bindToObservable\n//\n// @param {Node} node DOM Node to be modified.\n// @param {String} styleName Name of the style to be modified.\n// @returns {Object}\nfunction getStyleUpdater( el, styleName ) {\n\treturn {\n\t\tset( value ) {\n\t\t\tel.style[ styleName ] = value;\n\t\t},\n\n\t\tremove() {\n\t\t\tel.style[ styleName ] = null;\n\t\t}\n\t};\n}\n\n// Clones definition of the template.\n//\n// @param {module:ui/template~TemplateDefinition} def\n// @returns {module:ui/template~TemplateDefinition}\nfunction clone( def ) {\n\tconst clone = cloneDeepWith( def, value => {\n\t\t// Don't clone the `Template.bind`* bindings because of the references to Observable\n\t\t// and DomEmitterMixin instances inside, which would also be traversed and cloned by greedy\n\t\t// cloneDeepWith algorithm. There's no point in cloning Observable/DomEmitterMixins\n\t\t// along with the definition.\n\t\t//\n\t\t// Don't clone Template instances if provided as a child. They're simply #render()ed\n\t\t// and nothing should interfere.\n\t\t//\n\t\t// Also don't clone View instances if provided as a child of the Template. The template\n\t\t// instance will be extracted from the View during the normalization and there's no need\n\t\t// to clone it.\n\t\tif ( value && ( value instanceof TemplateBinding || isTemplate( value ) || isView( value ) || isViewCollection( value ) ) ) {\n\t\t\treturn value;\n\t\t}\n\t} );\n\n\treturn clone;\n}\n\n// Normalizes given {@link module:ui/template~TemplateDefinition}.\n//\n// See:\n// * {@link normalizeAttributes}\n// * {@link normalizeListeners}\n// * {@link normalizePlainTextDefinition}\n// * {@link normalizeTextDefinition}\n//\n// @param {module:ui/template~TemplateDefinition} def\n// @returns {module:ui/template~TemplateDefinition} Normalized definition.\nfunction normalize( def ) {\n\tif ( typeof def == 'string' ) {\n\t\tdef = normalizePlainTextDefinition( def );\n\t} else if ( def.text ) {\n\t\tnormalizeTextDefinition( def );\n\t}\n\n\tif ( def.on ) {\n\t\tdef.eventListeners = normalizeListeners( def.on );\n\n\t\t// Template mixes EmitterMixin, so delete #on to avoid collision.\n\t\tdelete def.on;\n\t}\n\n\tif ( !def.text ) {\n\t\tif ( def.attributes ) {\n\t\t\tnormalizeAttributes( def.attributes );\n\t\t}\n\n\t\tconst children = [];\n\n\t\tif ( def.children ) {\n\t\t\tif ( isViewCollection( def.children ) ) {\n\t\t\t\tchildren.push( def.children );\n\t\t\t} else {\n\t\t\t\tfor ( const child of def.children ) {\n\t\t\t\t\tif ( isTemplate( child ) || isView( child ) || isDomNode( child ) ) {\n\t\t\t\t\t\tchildren.push( child );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchildren.push( new Template( child ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdef.children = children;\n\t}\n\n\treturn def;\n}\n\n// Normalizes \"attributes\" section of {@link module:ui/template~TemplateDefinition}.\n//\n//\t\tattributes: {\n//\t\t\ta: 'bar',\n//\t\t\tb: {@link module:ui/template~TemplateBinding},\n//\t\t\tc: {\n//\t\t\t\tvalue: 'bar'\n//\t\t\t}\n//\t\t}\n//\n// becomes\n//\n//\t\tattributes: {\n//\t\t\ta: [ 'bar' ],\n//\t\t\tb: [ {@link module:ui/template~TemplateBinding} ],\n//\t\t\tc: {\n//\t\t\t\tvalue: [ 'bar' ]\n//\t\t\t}\n//\t\t}\n//\n// @param {Object} attrs\nfunction normalizeAttributes( attrs ) {\n\tfor ( const a in attrs ) {\n\t\tif ( attrs[ a ].value ) {\n\t\t\tattrs[ a ].value = [].concat( attrs[ a ].value );\n\t\t}\n\n\t\tarrayify( attrs, a );\n\t}\n}\n\n// Normalizes \"on\" section of {@link module:ui/template~TemplateDefinition}.\n//\n//\t\ton: {\n//\t\t\ta: 'bar',\n//\t\t\tb: {@link module:ui/template~TemplateBinding},\n//\t\t\tc: [ {@link module:ui/template~TemplateBinding}, () => { ... } ]\n//\t\t}\n//\n// becomes\n//\n//\t\ton: {\n//\t\t\ta: [ 'bar' ],\n//\t\t\tb: [ {@link module:ui/template~TemplateBinding} ],\n//\t\t\tc: [ {@link module:ui/template~TemplateBinding}, () => { ... } ]\n//\t\t}\n//\n// @param {Object} listeners\n// @returns {Object} Object containing normalized listeners.\nfunction normalizeListeners( listeners ) {\n\tfor ( const l in listeners ) {\n\t\tarrayify( listeners, l );\n\t}\n\n\treturn listeners;\n}\n\n// Normalizes \"string\" {@link module:ui/template~TemplateDefinition}.\n//\n//\t\t\"foo\"\n//\n// becomes\n//\n//\t\t{ text: [ 'foo' ] },\n//\n// @param {String} def\n// @returns {module:ui/template~TemplateDefinition} Normalized template definition.\nfunction normalizePlainTextDefinition( def ) {\n\treturn {\n\t\ttext: [ def ]\n\t};\n}\n\n// Normalizes text {@link module:ui/template~TemplateDefinition}.\n//\n//\t\tchildren: [\n//\t\t\t{ text: 'def' },\n//\t\t\t{ text: {@link module:ui/template~TemplateBinding} }\n//\t\t]\n//\n// becomes\n//\n//\t\tchildren: [\n//\t\t\t{ text: [ 'def' ] },\n//\t\t\t{ text: [ {@link module:ui/template~TemplateBinding} ] }\n//\t\t]\n//\n// @param {module:ui/template~TemplateDefinition} def\nfunction normalizeTextDefinition( def ) {\n\tif ( !Array.isArray( def.text ) ) {\n\t\tdef.text = [ def.text ];\n\t}\n}\n\n// Wraps an entry in Object in an Array, if not already one.\n//\n//\t\t{\n//\t\t\tx: 'y',\n//\t\t\ta: [ 'b' ]\n//\t\t}\n//\n// becomes\n//\n//\t\t{\n//\t\t\tx: [ 'y' ],\n//\t\t\ta: [ 'b' ]\n//\t\t}\n//\n// @param {Object} obj\n// @param {String} key\nfunction arrayify( obj, key ) {\n\tif ( !Array.isArray( obj[ key ] ) ) {\n\t\tobj[ key ] = [ obj[ key ] ];\n\t}\n}\n\n// A helper which concatenates the value avoiding unwanted\n// leading white spaces.\n//\n// @param {String} prev\n// @param {String} cur\n// @returns {String}\nfunction arrayValueReducer( prev, cur ) {\n\tif ( isFalsy( cur ) ) {\n\t\treturn prev;\n\t} else if ( isFalsy( prev ) ) {\n\t\treturn cur;\n\t} else {\n\t\treturn `${ prev } ${ cur }`;\n\t}\n}\n\n// Extends one object defined in the following format:\n//\n//\t\t{\n//\t\t\tkey1: [Array1],\n//\t\t\tkey2: [Array2],\n//\t\t\t...\n//\t\t\tkeyN: [ArrayN]\n//\t\t}\n//\n// with another object of the same data format.\n//\n// @param {Object} obj Base object.\n// @param {Object} ext Object extending base.\n// @returns {String}\nfunction extendObjectValueArray( obj, ext ) {\n\tfor ( const a in ext ) {\n\t\tif ( obj[ a ] ) {\n\t\t\tobj[ a ].push( ...ext[ a ] );\n\t\t} else {\n\t\t\tobj[ a ] = ext[ a ];\n\t\t}\n\t}\n}\n\n// A helper for {@link module:ui/template~Template#extend}. Recursively extends {@link module:ui/template~Template} instance\n// with content from {module:ui/template~TemplateDefinition}. See {@link module:ui/template~Template#extend} to learn more.\n//\n// @param {module:ui/template~Template} def A template instance to be extended.\n// @param {module:ui/template~TemplateDefinition} def A definition which is to extend the template instance.\nfunction extendTemplate( template, def ) {\n\tif ( def.attributes ) {\n\t\tif ( !template.attributes ) {\n\t\t\ttemplate.attributes = {};\n\t\t}\n\n\t\textendObjectValueArray( template.attributes, def.attributes );\n\t}\n\n\tif ( def.eventListeners ) {\n\t\tif ( !template.eventListeners ) {\n\t\t\ttemplate.eventListeners = {};\n\t\t}\n\n\t\textendObjectValueArray( template.eventListeners, def.eventListeners );\n\t}\n\n\tif ( def.text ) {\n\t\ttemplate.text.push( ...def.text );\n\t}\n\n\tif ( def.children && def.children.length ) {\n\t\tif ( template.children.length != def.children.length ) {\n\t\t\t/**\n\t\t\t * The number of children in extended definition does not match.\n\t\t\t *\n\t\t\t * @error ui-template-extend-children-mismatch\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'ui-template-extend-children-mismatch: The number of children in extended definition does not match.'\n\t\t\t);\n\t\t}\n\n\t\tlet childIndex = 0;\n\n\t\tfor ( const childDef of def.children ) {\n\t\t\textendTemplate( template.children[ childIndex++ ], childDef );\n\t\t}\n\t}\n}\n\n// Checks if value is \"falsy\".\n// Note: 0 (Number) is not \"falsy\" in this context.\n//\n// @private\n// @param {*} value Value to be checked.\nfunction isFalsy( value ) {\n\treturn !value && value !== 0;\n}\n\n// Checks if the item is an instance of {@link module:ui/view~View}\n//\n// @private\n// @param {*} value Value to be checked.\nfunction isView( item ) {\n\treturn item instanceof View;\n}\n\n// Checks if the item is an instance of {@link module:ui/template~Template}\n//\n// @private\n// @param {*} value Value to be checked.\nfunction isTemplate( item ) {\n\treturn item instanceof Template;\n}\n\n// Checks if the item is an instance of {@link module:ui/viewcollection~ViewCollection}\n//\n// @private\n// @param {*} value Value to be checked.\nfunction isViewCollection( item ) {\n\treturn item instanceof ViewCollection;\n}\n\n// Creates an empty skeleton for {@link module:ui/template~Template#revert}\n// data.\n//\n// @private\nfunction getEmptyRevertData() {\n\treturn {\n\t\tchildren: [],\n\t\tbindings: [],\n\t\tattributes: {}\n\t};\n}\n\n// Checks whether an attribute should be extended when\n// {@link module:ui/template~Template#apply} is called.\n//\n// @private\n// @param {String} attrName Attribute name to check.\nfunction shouldExtend( attrName ) {\n\treturn attrName == 'class' || attrName == 'style';\n}\n\n/**\n * A definition of the {@link module:ui/template~Template}. It describes what kind of\n * node a template will render (HTML element or text), attributes of an element, DOM event\n * listeners and children.\n *\n * Also see:\n * * {@link module:ui/template~TemplateValueSchema} to learn about HTML element attributes,\n * * {@link module:ui/template~TemplateListenerSchema} to learn about DOM event listeners.\n *\n * A sample definition on an HTML element can look like this:\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\tchildren: [\n *\t\t\t\t{\n *\t\t\t\t\ttag: 'span',\n *\t\t\t\t\tattributes: { ... },\n *\t\t\t\t\tchildren: [ ... ],\n *\t\t\t\t},\n *\t\t\t\t{\n *\t\t\t\t\ttext: 'statictext'\n *\t\t\t\t},\n *\t\t\t\t'also-statictext',\n *\t\t\t],\n *\t\t\tattributes: {\n *\t\t\t\tclass: {@link module:ui/template~TemplateValueSchema},\n *\t\t\t\tid: {@link module:ui/template~TemplateValueSchema},\n *\t\t\t\tstyle: {@link module:ui/template~TemplateValueSchema}\n *\n *\t\t\t\t// ...\n *\t\t\t},\n *\t\t\ton: {\n *\t\t\t\t'click': {@link module:ui/template~TemplateListenerSchema}\n *\n *\t\t\t\t// Document.querySelector format is also accepted.\n *\t\t\t\t'keyup@a.some-class': {@link module:ui/template~TemplateListenerSchema}\n *\n *\t\t\t\t// ...\n *\t\t\t}\n *\t\t} );\n *\n * A {@link module:ui/view~View}, another {@link module:ui/template~Template} or a native DOM node\n * can also become a child of a template. When a view is passed, its {@link module:ui/view~View#element} is used:\n *\n *\t\tconst view = new SomeView();\n *\t\tconst childTemplate = new Template( { ... } );\n *\t\tconst childNode = document.createElement( 'b' );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\n *\t\t\tchildren: [\n *\t\t\t\t// view#element will be added as a child of this <p>.\n *\t\t\t\tview,\n *\n * \t\t\t\t// The output of childTemplate.render() will be added here.\n *\t\t\t\tchildTemplate,\n *\n *\t\t\t\t// Native DOM nodes are included directly in the rendered output.\n *\t\t\t\tchildNode\n *\t\t\t]\n *\t\t} );\n *\n * An entire {@link module:ui/viewcollection~ViewCollection} can be used as a child in the definition:\n *\n *\t\tconst collection = new ViewCollection();\n *\t\tcollection.add( someView );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\n *\t\t\tchildren: collection\n *\t\t} );\n *\n * @typedef module:ui/template~TemplateDefinition\n * @type Object\n *\n * @property {String} tag See the template {@link module:ui/template~Template#tag} property.\n *\n * @property {Array.<module:ui/template~TemplateDefinition>} [children]\n * See the template {@link module:ui/template~Template#children} property.\n *\n * @property {Object.<String, module:ui/template~TemplateValueSchema>} [attributes]\n * See the template {@link module:ui/template~Template#attributes} property.\n *\n * @property {String|module:ui/template~TemplateValueSchema|Array.<String|module:ui/template~TemplateValueSchema>} [text]\n * See the template {@link module:ui/template~Template#text} property.\n *\n * @property {Object.<String, module:ui/template~TemplateListenerSchema>} [on]\n * See the template {@link module:ui/template~Template#eventListeners} property.\n */\n\n/**\n * Describes a value of an HTML element attribute or `textContent`. It allows combining multiple\n * data sources like static values and {@link module:utils/observablemixin~Observable} attributes.\n *\n * Also see:\n * * {@link module:ui/template~TemplateDefinition} to learn where to use it,\n * * {@link module:ui/template~Template.bind} to learn how to configure\n * {@link module:utils/observablemixin~Observable} attribute bindings,\n * * {@link module:ui/template~Template#render} to learn how to render a template,\n * * {@link module:ui/template~BindChain#to `to()`} and {@link module:ui/template~BindChain#if `if()`}\n * methods to learn more about bindings.\n *\n * Attribute values can be described in many different ways:\n *\n *\t\t// Bind helper will create bindings to attributes of the observable.\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\tattributes: {\n *\t\t\t\t// A plain string schema.\n *\t\t\t\t'class': 'static-text',\n *\n *\t\t\t\t// An object schema, binds to the \"foo\" attribute of the\n *\t\t\t\t// observable and follows its value.\n *\t\t\t\t'class': bind.to( 'foo' ),\n *\n *\t\t\t\t// An array schema, combines the above.\n *\t\t\t\t'class': [\n *\t\t\t\t\t'static-text',\n *\t\t\t\t\tbind.to( 'bar', () => { ... } ),\n *\n * \t\t\t\t\t// Bindings can also be conditional.\n *\t\t\t\t\tbind.if( 'baz', 'class-when-baz-is-true' )\n *\t\t\t\t],\n *\n *\t\t\t\t// An array schema, with a custom namespace, e.g. useful for creating SVGs.\n *\t\t\t\t'class': {\n *\t\t\t\t\tns: 'http://ns.url',\n *\t\t\t\t\tvalue: [\n *\t\t\t\t\t\tbind.if( 'baz', 'value-when-true' ),\n *\t\t\t\t\t\t'static-text'\n *\t\t\t\t\t]\n *\t\t\t\t},\n *\n *\t\t\t\t// An object schema, specific for styles.\n *\t\t\t\tstyle: {\n *\t\t\t\t\tcolor: 'red',\n *\t\t\t\t\tbackgroundColor: bind.to( 'qux', () => { ... } )\n *\t\t\t\t}\n *\t\t\t}\n *\t\t} );\n *\n * Text nodes can also have complex values:\n *\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\t// Will render a \"foo\" text node.\n *\t\tnew Template( {\n *\t\t\ttext: 'foo'\n *\t\t} );\n *\n *\t\t// Will render a \"static text: {observable.foo}\" text node.\n *\t\t// The text of the node will be updated as the \"foo\" attribute changes.\n *\t\tnew Template( {\n *\t\t\ttext: [\n *\t\t\t\t'static text: ',\n *\t\t\t\tbind.to( 'foo', () => { ... } )\n *\t\t\t]\n *\t\t} );\n *\n * @typedef module:ui/template~TemplateValueSchema\n * @type {Object|String|Array}\n */\n\n/**\n * Describes an event listener attached to an HTML element. Such listener can propagate DOM events\n * through an {@link module:utils/observablemixin~Observable} instance, execute custom callbacks\n * or both, if necessary.\n *\n * Also see:\n * * {@link module:ui/template~TemplateDefinition} to learn more about template definitions,\n * * {@link module:ui/template~BindChain#to `to()`} method to learn more about bindings.\n *\n * Check out different ways of attaching event listeners below:\n *\n *\t\t// Bind helper will propagate events through the observable.\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\ton: {\n *\t\t\t\t// An object schema. The observable will fire the \"clicked\" event upon DOM \"click\".\n *\t\t\t\tclick: bind.to( 'clicked' )\n *\n *\t\t\t\t// An object schema. It will work for \"click\" event on \"a.foo\" children only.\n *\t\t\t\t'click@a.foo': bind.to( 'clicked' )\n *\n *\t\t\t\t// An array schema, makes the observable propagate multiple events.\n *\t\t\t\tclick: [\n *\t\t\t\t\tbind.to( 'clicked' ),\n *\t\t\t\t\tbind.to( 'executed' )\n *\t\t\t\t],\n *\n *\t\t\t\t// An array schema with a custom callback.\n *\t\t\t\t'click@a.foo': {\n *\t\t\t\t\tbind.to( 'clicked' ),\n *\t\t\t\t\tbind.to( evt => {\n *\t\t\t\t\t\tconsole.log( `${ evt.target } has been clicked!` );\n *\t\t\t\t\t} }\n *\t\t\t\t}\n *\t\t\t}\n *\t\t} );\n *\n * @typedef module:ui/template~TemplateListenerSchema\n * @type {Object|String|Array}\n */\n\n/**\n * The return value of {@link ~Template.bind `Template.bind()`}. It provides `to()` and `if()`\n * methods to create the {@link module:utils/observablemixin~Observable observable} attribute and event bindings.\n *\n * @interface module:ui/template~BindChain\n */\n\n/**\n * Binds an {@link module:utils/observablemixin~Observable observable} to either:\n *\n * * an HTML element attribute or a text node `textContent`, so it remains in sync with the observable\n * attribute as it changes,\n * * or an HTML element DOM event, so the DOM events are propagated through an observable.\n *\n * Some common use cases of `to()` bindings are presented below:\n *\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\tattributes: {\n *\t\t\t\t// class=\"...\" attribute gets bound to `observable#a`\n *\t\t\t\tclass: bind.to( 'a' )\n *\t\t\t},\n *\t\t\tchildren: [\n *\t\t\t\t// <p>...</p> gets bound to observable#b; always `toUpperCase()`.\n *\t\t\t\t{\n *\t\t\t\t\ttext: bind.to( 'b', ( value, node ) => value.toUpperCase() )\n *\t\t\t\t}\n *\t\t\t],\n *\t\t\ton: {\n *\t\t\t\tclick: [\n *\t\t\t\t\t// An observable will fire \"clicked\" upon \"click\" in the DOM.\n *\t\t\t\t\tbind.to( 'clicked' ),\n *\n *\t\t\t\t\t// A custom callback will be executed upon \"click\" in the DOM.\n *\t\t\t\t\tbind.to( () => {\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} ).render();\n *\n * Learn more about using `to()` in the {@link module:ui/template~TemplateValueSchema} and\n * {@link module:ui/template~TemplateListenerSchema}.\n *\n * @method #to\n * @param {String|Function} eventNameOrFunctionOrAttribute An attribute name of\n * {@link module:utils/observablemixin~Observable} or a DOM event name or an event callback.\n * @param {Function} [callback] Allows for processing of the value. Accepts `Node` and `value` as arguments.\n * @return {module:ui/template~TemplateBinding}\n */\n\n/**\n * Binds an {@link module:utils/observablemixin~Observable observable} to an HTML element attribute or a text\n * node `textContent` so it remains in sync with the observable attribute as it changes.\n *\n * Unlike {@link module:ui/template~BindChain#to}, it controls the presence of the attribute or `textContent`\n * depending on the \"falseness\" of an {@link module:utils/observablemixin~Observable} attribute.\n *\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'input',\n *\t\t\tattributes: {\n *\t\t\t\t// <input checked> when `observable#a` is not undefined/null/false/''\n *\t\t\t\t// <input> when `observable#a` is undefined/null/false\n *\t\t\t\tchecked: bind.if( 'a' )\n *\t\t\t},\n *\t\t\tchildren: [\n *\t\t\t\t{\n *\t\t\t\t\t// <input>\"b-is-not-set\"</input> when `observable#b` is undefined/null/false/''\n *\t\t\t\t\t// <input></input> when `observable#b` is not \"falsy\"\n *\t\t\t\t\ttext: bind.if( 'b', 'b-is-not-set', ( value, node ) => !value )\n *\t\t\t\t}\n *\t\t\t]\n *\t\t} ).render();\n *\n * Learn more about using `if()` in the {@link module:ui/template~TemplateValueSchema}.\n *\n * @method #if\n * @param {String} attribute An attribute name of {@link module:utils/observablemixin~Observable} used in the binding.\n * @param {String} [valueIfTrue] Value set when the {@link module:utils/observablemixin~Observable} attribute is not\n * undefined/null/false/'' (empty string).\n * @param {Function} [callback] Allows for processing of the value. Accepts `Node` and `value` as arguments.\n * @return {module:ui/template~TemplateBinding}\n */\n\n/**\n * The {@link module:ui/template~Template#_renderNode} configuration.\n *\n * @private\n * @interface module:ui/template~RenderData\n */\n\n/**\n * Tells {@link module:ui/template~Template#_renderNode} to render\n * children into `DocumentFragment` first and then append the fragment\n * to the parent element. It is a speed optimization.\n *\n * @member {Boolean} #intoFragment\n */\n\n/**\n * A node which is being rendered.\n *\n * @member {HTMLElement|Text} #node\n */\n\n/**\n * Indicates whether the {@module:ui/template~RenderNodeOptions#node} has\n * been provided by {@module:ui/template~Template#apply}.\n *\n * @member {Boolean} #isApplying\n */\n\n/**\n * An object storing the data that helps {@module:ui/template~Template#revert}\n * bringing back an element to its initial state, i.e. before\n * {@module:ui/template~Template#apply} was called.\n *\n * @member {Object} #revertData\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/template.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/view\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport ViewCollection from './viewcollection';\nimport Template from './template';\nimport DomEmitterMixin from '@ckeditor/ckeditor5-utils/src/dom/emittermixin';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * The basic view class, which represents an HTML element created out of a\n * {@link module:ui/view~View#template}. Views are building blocks of the user interface and handle\n * interaction\n *\n * Views {@link module:ui/view~View#registerChildren aggregate} children in\n * {@link module:ui/view~View#createCollection collections} and manage the life cycle of DOM\n * listeners e.g. by handling rendering and destruction.\n *\n * See the {@link module:ui/template~TemplateDefinition} syntax to learn more about shaping view\n * elements, attributes and listeners.\n *\n *\t\tclass SampleView extends View {\n *\t\t\tconstructor( locale ) {\n *\t\t\t\tsuper( locale );\n *\n *\t\t\t\tconst bind = this.bindTemplate;\n *\n *\t\t\t\t// Views define their interface (state) using observable attributes.\n *\t\t\t\tthis.set( 'elementClass', 'bar' );\n *\n *\t\t\t\tthis.setTemplate( {\n *\t\t\t\t\ttag: 'p',\n *\n *\t\t\t\t\t// The element of the view can be defined with its children.\n *\t\t\t\t\tchildren: [\n *\t\t\t\t\t\t'Hello',\n *\t\t\t\t\t\t{\n *\t\t\t\t\t\t\ttag: 'b',\n *\t\t\t\t\t\t\tchildren: [ 'world!' ]\n *\t\t\t\t\t\t}\n *\t\t\t\t\t],\n *\t\t\t\t\tattributes: {\n *\t\t\t\t\t\tclass: [\n *\t\t\t\t\t\t\t'foo',\n *\n *\t\t\t\t\t\t\t// Observable attributes control the state of the view in DOM.\n *\t\t\t\t\t\t\tbind.to( 'elementClass' )\n *\t\t\t\t\t\t]\n *\t\t\t\t\t},\n *\t\t\t\t\ton: {\n *\t\t\t\t\t\t// Views listen to DOM events and propagate them.\n *\t\t\t\t\t\tclick: bind.to( 'clicked' )\n *\t\t\t\t\t}\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n *\t\tconst view = new SampleView( locale );\n *\n *\t\tview.render();\n *\n *\t\t// Append <p class=\"foo bar\">Hello<b>world</b></p> to the <body>\n *\t\tdocument.body.appendChild( view.element );\n *\n *\t\t// Change the class attribute to <p class=\"foo baz\">Hello<b>world</b></p>\n *\t\tview.elementClass = 'baz';\n *\n *\t\t// Respond to the \"click\" event in DOM by executing a custom action.\n *\t\tview.on( 'clicked', () => {\n *\t\t\tconsole.log( 'The view has been clicked!' );\n *\t\t} );\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class View {\n\t/**\n\t * Creates an instance of the {@link module:ui/view~View} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The localization services instance.\n\t */\n\tconstructor( locale ) {\n\t\t/**\n\t\t * An HTML element of the view. `null` until {@link #render rendered}\n\t\t * from the {@link #template}.\n\t\t *\n\t\t *\t\tclass SampleView extends View {\n\t\t *\t\t\tconstructor() {\n\t\t *\t\t\t\tsuper();\n\t\t *\n\t\t *\t\t\t\t// A template instance the #element will be created from.\n\t\t *\t\t\t\tthis.setTemplate( {\n\t\t *\t\t\t\t\ttag: 'p'\n\t\t *\n\t\t *\t\t\t\t\t// ...\n\t\t *\t\t\t\t} );\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\tconst view = new SampleView();\n\t\t *\n\t\t *\t\t// Renders the #template\n\t\t *\t\tview.render();\n\t\t *\n\t\t *\t\t// Append the HTML element of the view to <body>.\n\t\t *\t\tdocument.body.appendChild( view.element );\n\t\t *\n\t\t * **Note**: The element of the view can also be assigned directly:\n\t\t *\n\t\t *\t\tview.element = document.querySelector( '#my-container' );\n\t\t *\n\t\t * @member {HTMLElement}\n\t\t */\n\t\tthis.element = null;\n\n\t\t/**\n\t\t * Set `true` when the view has already been {@link module:ui/view~View#render rendered}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isRendered\n\t\t */\n\t\tthis.isRendered = false;\n\n\t\t/**\n\t\t * A set of tools to localize the user interface.\n\t\t *\n\t\t * Also see {@link module:core/editor/editor~Editor#locale}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/locale~Locale}\n\t\t */\n\t\tthis.locale = locale;\n\n\t\t/**\n\t\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t\t *\n\t\t * Note: If {@link #locale} instance hasn't been passed to the view this method may not\n\t\t * be available.\n\t\t *\n\t\t * @see module:utils/locale~Locale#t\n\t\t * @method\n\t\t */\n\t\tthis.t = locale && locale.t;\n\n\t\t/**\n\t\t * Collections registered with {@link #createCollection}.\n\t\t *\n\t\t * @protected\n\t\t * @member {Set.<module:ui/viewcollection~ViewCollection>}\n\t\t */\n\t\tthis._viewCollections = new Collection();\n\n\t\t/**\n\t\t * A collection of view instances, which have been added directly\n\t\t * into the {@link module:ui/template~Template#children}.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis._unboundChildren = this.createCollection();\n\n\t\t// Pass parent locale to its children.\n\t\tthis._viewCollections.on( 'add', ( evt, collection ) => {\n\t\t\tcollection.locale = locale;\n\t\t} );\n\n\t\t/**\n\t\t * Template of this view. It provides the {@link #element} representing\n\t\t * the view in DOM, which is {@link #render rendered}.\n\t\t *\n\t\t * @member {module:ui/template~Template} #template\n\t\t */\n\n\t\t/**\n\t\t * Cached {@link @link module:ui/template~BindChain bind chain} object created by the\n\t\t * {@link #template}. See {@link #bindTemplate}.\n\t\t *\n\t\t * @private\n\t\t * @member {Object} #_bindTemplate\n\t\t */\n\t}\n\n\t/**\n\t * Shorthand for {@link module:ui/template~Template.bind}, a binding\n\t * {@link module:ui/template~BindChain interface} preconfigured for the view instance.\n\t *\n\t * It provides {@link module:ui/template~BindChain#to `to()`} and\n\t * {@link module:ui/template~BindChain#if `if()`} methods that initialize bindings with\n\t * observable attributes and attach DOM listeners.\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor( locale ) {\n\t *\t\t\t\tsuper( locale );\n\t *\n\t *\t\t\t\tconst bind = this.bindTemplate;\n\t *\n\t *\t\t\t\t// These {@link module:utils/observablemixin~Observable observable} attributes will control\n\t *\t\t\t\t// the state of the view in DOM.\n\t *\t\t\t\tthis.set( {\n\t *\t\t\t\t\telementClass: 'foo',\n\t *\t\t\t\t \tisEnabled: true\n\t *\t\t\t\t } );\n\t *\n\t *\t\t\t\tthis.setTemplate( {\n\t *\t\t\t\t\ttag: 'p',\n\t *\n\t *\t\t\t\t\tattributes: {\n\t *\t\t\t\t\t\t// The class HTML attribute will follow elementClass\n\t *\t\t\t\t\t\t// and isEnabled view attributes.\n\t *\t\t\t\t\t\tclass: [\n\t *\t\t\t\t\t\t\tbind.to( 'elementClass' )\n\t *\t\t\t\t\t\t\tbind.if( 'isEnabled', 'present-when-enabled' )\n\t *\t\t\t\t\t\t]\n\t *\t\t\t\t\t},\n\t *\n\t *\t\t\t\t\ton: {\n\t *\t\t\t\t\t\t// The view will fire the \"clicked\" event upon clicking <p> in DOM.\n\t *\t\t\t\t\t\tclick: bind.to( 'clicked' )\n\t *\t\t\t\t\t}\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t * @method #bindTemplate\n\t */\n\tget bindTemplate() {\n\t\tif ( this._bindTemplate ) {\n\t\t\treturn this._bindTemplate;\n\t\t}\n\n\t\treturn ( this._bindTemplate = Template.bind( this, this ) );\n\t}\n\n\t/**\n\t * Creates a new collection of views, which can be used as\n\t * {@link module:ui/template~Template#children} of this view.\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor( locale ) {\n\t *\t\t\t\tsuper( locale );\n\t *\n\t *\t\t\t\tthis.items = this.createCollection();\n \t *\n\t *\t\t\t\tthis.setTemplate( {\n\t *\t\t\t\t\ttag: 'p',\n\t *\n\t *\t\t\t\t\t// `items` collection will render here.\n\t *\t\t\t\t\tchildren: this.items\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst view = new SampleView( locale );\n\t *\t\tconst child = new ChildView( locale );\n\t *\n\t *\t\tview.render();\n\t *\n\t *\t\t// It will append <p></p> to the <body>.\n\t *\t\tdocument.body.appendChild( view.element );\n\t *\n\t *\t\t// From now on the child is nested under its parent, which is also reflected in DOM.\n\t *\t\t// <p><child#element></p>\n\t *\t\tview.items.add( child );\n\t *\n\t * @returns {module:ui/viewcollection~ViewCollection} A new collection of view instances.\n\t */\n\tcreateCollection() {\n\t\tconst collection = new ViewCollection();\n\n\t\tthis._viewCollections.add( collection );\n\n\t\treturn collection;\n\t}\n\n\t/**\n\t * Registers a new child view under the view instance. Once registered, a child\n\t * view is managed by its parent, including {@link #render rendering}\n\t * and {@link #destroy destruction}.\n\t *\n\t * To revert this, use {@link #deregisterChildren}.\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor( locale ) {\n\t *\t\t\t\tsuper( locale );\n\t *\n\t *\t\t\t\tthis.childA = new SomeChildView( locale );\n\t *\t\t\t\tthis.childB = new SomeChildView( locale );\n\t *\n\t *\t\t\t\tthis.setTemplate( { tag: 'p' } );\n\t *\n\t *\t\t\t\t// Register the children.\n\t *\t\t\t\tthis.registerChildren( [ this.childA, this.childB ] );\n\t *\t\t\t}\n\t *\n\t *\t\t\trender() {\n\t *\t\t\t\tsuper.render();\n\t *\n\t *\t\t\t\tthis.element.appendChild( this.childA.element );\n\t *\t\t\t\tthis.element.appendChild( this.childB.element );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst view = new SampleView( locale );\n\t *\n\t *\t\tview.render();\n\t *\n\t *\t\t// Will append <p><childA#element><b></b><childB#element></p>.\n\t *\t\tdocument.body.appendChild( view.element );\n\t *\n\t * **Note**: There's no need to add child views if they're already referenced in the\n\t * {@link #template}:\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor( locale ) {\n\t *\t\t\t\tsuper( locale );\n\t *\n\t *\t\t\t\tthis.childA = new SomeChildView( locale );\n\t *\t\t\t\tthis.childB = new SomeChildView( locale );\n\t *\n\t *\t\t\t\tthis.setTemplate( {\n\t *\t\t\t\t\ttag: 'p',\n\t *\n \t *\t\t\t\t\t// These children will be added automatically. There's no\n \t *\t\t\t\t\t// need to call {@link #registerChildren} for any of them.\n\t *\t\t\t\t\tchildren: [ this.childA, this.childB ]\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\n\t *\t\t\t// ...\n\t *\t\t}\n\t *\n\t * @param {module:ui/view~View|Iterable.<module:ui/view~View>} children Children views to be registered.\n\t */\n\tregisterChildren( children ) {\n\t\tif ( !isIterable( children ) ) {\n\t\t\tchildren = [ children ];\n\t\t}\n\n\t\tfor ( const child of children ) {\n\t\t\tthis._unboundChildren.add( child );\n\t\t}\n\t}\n\n\t/**\n\t * The opposite of {@link #registerChildren}. Removes a child view from this view instance.\n\t * Once removed, the child is no longer managed by its parent, e.g. it can safely\n\t * become a child of another parent view.\n\t *\n\t * @see #registerChildren\n\t * @param {module:ui/view~View|Iterable.<module:ui/view~View>} children Child views to be removed.\n\t */\n\tderegisterChildren( children ) {\n\t\tif ( !isIterable( children ) ) {\n\t\t\tchildren = [ children ];\n\t\t}\n\n\t\tfor ( const child of children ) {\n\t\t\tthis._unboundChildren.remove( child );\n\t\t}\n\t}\n\n\t/**\n\t * Sets the {@link #template} of the view with with given definition.\n\t *\n\t * A shorthand for:\n\t *\n\t *\t\tview.setTemplate( definition );\n\t *\n\t * @param {module:ui/template~TemplateDefinition} definition Definition of view's template.\n\t */\n\tsetTemplate( definition ) {\n\t\tthis.template = new Template( definition );\n\t}\n\n\t/**\n\t * {@link module:ui/template~Template.extend Extends} the {@link #template} of the view with\n\t * with given definition.\n\t *\n\t * A shorthand for:\n\t *\n\t *\t\tTemplate.extend( view.template, definition );\n\t *\n\t * **Note**: Is requires the {@link #template} to be already set. See {@link #setTemplate}.\n\t *\n\t * @param {module:ui/template~TemplateDefinition} definition Definition which\n\t * extends the {@link #template}.\n\t */\n\textendTemplate( definition ) {\n\t\tTemplate.extend( this.template, definition );\n\t}\n\n\t/**\n\t * Recursively renders the view.\n\t *\n\t * Once the view is rendered:\n\t * * the {@link #element} becomes an HTML element out of {@link #template},\n\t * * the {@link #isRendered} flag is set `true`.\n\t *\n\t * **Note**: The children of the view:\n\t * * defined directly in the {@link #template}\n\t * * residing in collections created by the {@link #createCollection} method,\n\t * * and added by {@link #registerChildren}\n\t * are also rendered in the process.\n\t *\n\t * In general, `render()` method is the right place to keep the code which refers to the\n\t * {@link #element} and should be executed at the very beginning of the view's life cycle.\n\t *\n\t * It is possible to {@link module:ui/template~Template.extend} the {@link #template} before\n\t * the view is rendered. To allow an early customization of the view (e.g. by its parent),\n\t * such references should be done in `render()`.\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor() {\n\t *\t\t\t\tthis.setTemplate( {\n\t *\t\t\t\t\t// ...\n\t *\t\t\t\t} );\n\t *\t\t\t},\n\t *\n\t *\t\t\trender() {\n\t *\t\t\t\t// View#element becomes available.\n\t *\t\t\t\tsuper.render();\n\t *\n\t *\t\t\t\t// The \"scroll\" listener depends on #element.\n\t *\t\t\t\tthis.listenTo( window, 'scroll', () => {\n\t *\t\t\t\t\t// A reference to #element would render the #template and make it non-extendable.\n\t *\t\t\t\t\tif ( window.scrollY > 0 ) {\n\t *\t\t\t\t\t\tthis.element.scrollLeft = 100;\n\t *\t\t\t\t\t} else {\n\t *\t\t\t\t\t\tthis.element.scrollLeft = 0;\n\t *\t\t\t\t\t}\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst view = new SampleView();\n\t *\n\t *\t\t// Let's customize the view before it gets rendered.\n\t *\t\tview.extendTemplate( {\n\t *\t\t\tattributes: {\n\t *\t\t\t\tclass: [\n\t *\t\t\t\t\t'additional-class'\n\t *\t\t\t\t]\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\t// Late rendering allows customization of the view.\n\t *\t\tview.render();\n\t */\n\trender() {\n\t\tif ( this.isRendered ) {\n\t\t\t/**\n\t\t\t * This View has already been rendered.\n\t\t\t *\n\t\t\t * @error ui-view-render-rendered\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'ui-view-render-already-rendered: This View has already been rendered.' );\n\t\t}\n\n\t\t// Render #element of the view.\n\t\tif ( this.template ) {\n\t\t\tthis.element = this.template.render();\n\n\t\t\t// Autoregister view children from #template.\n\t\t\tthis.registerChildren( this.template.getViews() );\n\t\t}\n\n\t\tthis.isRendered = true;\n\t}\n\n\t/**\n\t * Recursively destroys the view instance and child views added by {@link #registerChildren} and\n\t * residing in collections created by the {@link #createCollection}.\n\t *\n\t * Destruction disables all event listeners:\n\t * * created on the view, e.g. `view.on( 'event', () => {} )`,\n\t * * defined in the {@link #template} for DOM events.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\n\t\tthis._viewCollections.map( c => c.destroy() );\n\t}\n}\n\nmix( View, DomEmitterMixin );\nmix( View, ObservableMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/view.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/getpositionedancestor\n */\n\nimport global from './global';\n\n/**\n * For a given element, returns the nearest ancestor element which CSS position is not \"static\".\n *\n * @param {HTMLElement} element Native DOM element to be checked.\n * @returns {HTMLElement|null}\n */\nexport default function getPositionedAncestor( element ) {\n\twhile ( element && element.tagName.toLowerCase() != 'html' ) {\n\t\tif ( global.window.getComputedStyle( element ).position != 'static' ) {\n\t\t\treturn element;\n\t\t}\n\n\t\telement = element.parentElement;\n\t}\n\n\treturn null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/getpositionedancestor.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/position\n */\n\nimport global from './global';\nimport Rect from './rect';\nimport getPositionedAncestor from './getpositionedancestor';\nimport getBorderWidths from './getborderwidths';\nimport isFunction from '../lib/lodash/isFunction';\n\n/**\n * Calculates the `position: absolute` coordinates of a given element so it can be positioned with respect to the\n * target in the visually most efficient way, taking various restrictions like viewport or limiter geometry\n * into consideration.\n *\n *\t\t// The element which is to be positioned.\n *\t\tconst element = document.body.querySelector( '#toolbar' );\n *\n *\t\t// A target to which the element is positioned relatively.\n *\t\tconst target = document.body.querySelector( '#container' );\n *\n *\t\t// Finding the optimal coordinates for the positioning.\n *\t\tconst { left, top, name } = getOptimalPosition( {\n *\t\t\telement: element,\n *\t\t\ttarget: target,\n *\n * \t\t\t// The algorithm will chose among these positions to meet the requirements such\n * \t\t\t// as \"limiter\" element or \"fitInViewport\", set below. The positions are considered\n * \t\t\t// in the order of the array.\n *\t\t\tpositions: [\n *\t\t\t\t//\n *\t\t\t \t//\t[ Target ]\n *\t\t\t\t//\t+-----------------+\n *\t\t\t\t//\t| Element |\n *\t\t\t\t//\t+-----------------+\n *\t\t\t\t//\n *\t\t\t\ttargetRect => ( {\n *\t\t\t\t\ttop: targetRect.bottom,\n *\t\t\t\t\tleft: targetRect.left,\n *\t\t\t\t\tname: 'mySouthEastPosition'\n *\t\t\t\t} ),\n *\n *\t\t\t\t//\n *\t\t\t\t//\t+-----------------+\n *\t\t\t\t//\t| Element |\n *\t\t\t\t//\t+-----------------+\n *\t\t\t\t//\t[ Target ]\n *\t\t\t\t//\n *\t\t\t\t( targetRect, elementRect ) => ( {\n *\t\t\t\t\ttop: targetRect.top - elementRect.height,\n *\t\t\t\t\tleft: targetRect.left,\n *\t\t\t\t\tname: 'myNorthEastPosition'\n *\t\t\t\t} )\n *\t\t\t],\n *\n *\t\t\t// Find a position such guarantees the element remains within visible boundaries of <body>.\n *\t\t\tlimiter: document.body,\n *\n *\t\t\t// Find a position such guarantees the element remains within visible boundaries of the browser viewport.\n *\t\t\tfitInViewport: true\n *\t\t} );\n *\n *\t\t// The best position which fits into document.body and the viewport. May be useful\n *\t\t// to set proper class on the `element`.\n *\t\tconsole.log( name ); -> \"myNorthEastPosition\"\n *\n *\t\t// Using the absolute coordinates which has been found to position the element\n *\t\t// as in the diagram depicting the \"myNorthEastPosition\" position.\n *\t\telement.style.top = top;\n *\t\telement.style.left = left;\n *\n * @param {module:utils/dom/position~Options} options Positioning options object.\n * @returns {module:utils/dom/position~Position}\n */\nexport function getOptimalPosition( { element, target, positions, limiter, fitInViewport } ) {\n\t// If the {@link module:utils/dom/position~Options#target} is a function, use what it returns.\n\t// https://github.com/ckeditor/ckeditor5-utils/issues/157\n\tif ( isFunction( target ) ) {\n\t\ttarget = target();\n\t}\n\n\t// If the {@link module:utils/dom/position~Options#limiter} is a function, use what it returns.\n\t// https://github.com/ckeditor/ckeditor5-ui/issues/260\n\tif ( isFunction( limiter ) ) {\n\t\tlimiter = limiter();\n\t}\n\n\tconst positionedElementAncestor = getPositionedAncestor( element.parentElement );\n\tconst elementRect = new Rect( element );\n\tconst targetRect = new Rect( target );\n\n\tlet bestPosition;\n\tlet name;\n\n\t// If there are no limits, just grab the very first position and be done with that drama.\n\tif ( !limiter && !fitInViewport ) {\n\t\t[ name, bestPosition ] = getPosition( positions[ 0 ], targetRect, elementRect );\n\t} else {\n\t\tconst limiterRect = limiter && new Rect( limiter ).getVisible();\n\t\tconst viewportRect = fitInViewport && new Rect( global.window );\n\n\t\t[ name, bestPosition ] =\n\t\t\tgetBestPosition( positions, targetRect, elementRect, limiterRect, viewportRect ) ||\n\t\t\t// If there's no best position found, i.e. when all intersections have no area because\n\t\t\t// rects have no width or height, then just use the first available position.\n\t\t\tgetPosition( positions[ 0 ], targetRect, elementRect );\n\t}\n\n\tlet { left, top } = getAbsoluteRectCoordinates( bestPosition );\n\n\tif ( positionedElementAncestor ) {\n\t\tconst ancestorPosition = getAbsoluteRectCoordinates( new Rect( positionedElementAncestor ) );\n\t\tconst ancestorBorderWidths = getBorderWidths( positionedElementAncestor );\n\n\t\t// (https://github.com/ckeditor/ckeditor5-ui-default/issues/126)\n\t\t// If there's some positioned ancestor of the panel, then its `Rect` must be taken into\n\t\t// consideration. `Rect` is always relative to the viewport while `position: absolute` works\n\t\t// with respect to that positioned ancestor.\n\t\tleft -= ancestorPosition.left;\n\t\ttop -= ancestorPosition.top;\n\n\t\t// (https://github.com/ckeditor/ckeditor5-utils/issues/139)\n\t\t// If there's some positioned ancestor of the panel, not only its position must be taken into\n\t\t// consideration (see above) but also its internal scrolls. Scroll have an impact here because `Rect`\n\t\t// is relative to the viewport (it doesn't care about scrolling), while `position: absolute`\n\t\t// must compensate that scrolling.\n\t\tleft += positionedElementAncestor.scrollLeft;\n\t\ttop += positionedElementAncestor.scrollTop;\n\n\t\t// (https://github.com/ckeditor/ckeditor5-utils/issues/139)\n\t\t// If there's some positioned ancestor of the panel, then its `Rect` includes its CSS `borderWidth`\n\t\t// while `position: absolute` positioning does not consider it.\n\t\t// E.g. `{ position: absolute, top: 0, left: 0 }` means upper left corner of the element,\n\t\t// not upper-left corner of its border.\n\t\tleft -= ancestorBorderWidths.left;\n\t\ttop -= ancestorBorderWidths.top;\n\t}\n\n\treturn { left, top, name };\n}\n\n// For given position function, returns a corresponding `Rect` instance.\n//\n// @private\n// @param {Function} position A function returning {@link module:utils/dom/position~Position}.\n// @param {utils/dom/rect~Rect} targetRect A rect of the target.\n// @param {utils/dom/rect~Rect} elementRect A rect of positioned element.\n// @returns {Array} An array containing position name and its Rect.\nfunction getPosition( position, targetRect, elementRect ) {\n\tconst { left, top, name } = position( targetRect, elementRect );\n\n\treturn [ name, elementRect.clone().moveTo( left, top ) ];\n}\n\n// For a given array of positioning functions, returns such that provides the best\n// fit of the `elementRect` into the `limiterRect` and `viewportRect`.\n//\n// @private\n// @param {module:utils/dom/position~Options#positions} positions Functions returning\n// {@link module:utils/dom/position~Position} to be checked, in the order of preference.\n// @param {utils/dom/rect~Rect} targetRect A rect of the {@link module:utils/dom/position~Options#target}.\n// @param {utils/dom/rect~Rect} elementRect A rect of positioned {@link module:utils/dom/position~Options#element}.\n// @param {utils/dom/rect~Rect} limiterRect A rect of the {@link module:utils/dom/position~Options#limiter}.\n// @param {utils/dom/rect~Rect} viewportRect A rect of the viewport.\n// @returns {Array} An array containing the name of the position and it's rect.\nfunction getBestPosition( positions, targetRect, elementRect, limiterRect, viewportRect ) {\n\tlet maxLimiterIntersectArea = 0;\n\tlet maxViewportIntersectArea = 0;\n\tlet bestPositionRect;\n\tlet bestPositionName;\n\n\t// This is when element is fully visible.\n\tconst elementRectArea = elementRect.getArea();\n\n\tpositions.some( position => {\n\t\tconst [ positionName, positionRect ] = getPosition( position, targetRect, elementRect );\n\t\tlet limiterIntersectArea;\n\t\tlet viewportIntersectArea;\n\n\t\tif ( limiterRect ) {\n\t\t\tif ( viewportRect ) {\n\t\t\t\t// Consider only the part of the limiter which is visible in the viewport. So the limiter is getting limited.\n\t\t\t\tconst limiterViewportIntersectRect = limiterRect.getIntersection( viewportRect );\n\n\t\t\t\tif ( limiterViewportIntersectRect ) {\n\t\t\t\t\t// If the limiter is within the viewport, then check the intersection between that part of the\n\t\t\t\t\t// limiter and actual position.\n\t\t\t\t\tlimiterIntersectArea = limiterViewportIntersectRect.getIntersectionArea( positionRect );\n\t\t\t\t} else {\n\t\t\t\t\tlimiterIntersectArea = 0;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlimiterIntersectArea = limiterRect.getIntersectionArea( positionRect );\n\t\t\t}\n\t\t}\n\n\t\tif ( viewportRect ) {\n\t\t\tviewportIntersectArea = viewportRect.getIntersectionArea( positionRect );\n\t\t}\n\n\t\t// The only criterion: intersection with the viewport.\n\t\tif ( viewportRect && !limiterRect ) {\n\t\t\tif ( viewportIntersectArea > maxViewportIntersectArea ) {\n\t\t\t\tsetBestPosition();\n\t\t\t}\n\t\t}\n\t\t// The only criterion: intersection with the limiter.\n\t\telse if ( !viewportRect && limiterRect ) {\n\t\t\tif ( limiterIntersectArea > maxLimiterIntersectArea ) {\n\t\t\t\tsetBestPosition();\n\t\t\t}\n\t\t}\n\t\t// Two criteria: intersection with the viewport and the limiter visible in the viewport.\n\t\telse {\n\t\t\tif ( viewportIntersectArea > maxViewportIntersectArea && limiterIntersectArea >= maxLimiterIntersectArea ) {\n\t\t\t\tsetBestPosition();\n\t\t\t} else if ( viewportIntersectArea >= maxViewportIntersectArea && limiterIntersectArea > maxLimiterIntersectArea ) {\n\t\t\t\tsetBestPosition();\n\t\t\t}\n\t\t}\n\n\t\tfunction setBestPosition() {\n\t\t\tmaxViewportIntersectArea = viewportIntersectArea;\n\t\t\tmaxLimiterIntersectArea = limiterIntersectArea;\n\t\t\tbestPositionRect = positionRect;\n\t\t\tbestPositionName = positionName;\n\t\t}\n\n\t\t// If a such position is found that element is fully container by the limiter then, obviously,\n\t\t// there will be no better one, so finishing.\n\t\treturn limiterIntersectArea === elementRectArea;\n\t} );\n\n\treturn bestPositionRect ? [ bestPositionName, bestPositionRect ] : null;\n}\n\n// DOMRect (also Rect) works in a scrollindependent geometry but `position: absolute` doesn't.\n// This function converts Rect to `position: absolute` coordinates.\n//\n// @private\n// @param {utils/dom/rect~Rect} rect A rect to be converted.\n// @returns {Object} Object containing `left` and `top` properties, in absolute coordinates.\nfunction getAbsoluteRectCoordinates( { left, top } ) {\n\tconst { scrollX, scrollY } = global.window;\n\n\treturn {\n\t\tleft: left + scrollX,\n\t\ttop: top + scrollY,\n\t};\n}\n\n/**\n * The `getOptimalPosition` helper options.\n *\n * @interface module:utils/dom/position~Options\n */\n\n/**\n * Element that is to be positioned.\n *\n * @member {HTMLElement} #element\n */\n\n/**\n * Target with respect to which the `element` is to be positioned.\n *\n * @member {HTMLElement|Range|ClientRect|Rect|Function} #target\n */\n\n/**\n * An array of functions which return {@link module:utils/dom/position~Position} relative\n * to the `target`, in the order of preference.\n *\n * @member {Array.<Function>} #positions\n */\n\n/**\n * When set, the algorithm will chose position which fits the most in the\n * limiter's bounding rect.\n *\n * @member {HTMLElement|Range|ClientRect|Rect|Function} #limiter\n */\n\n/**\n * When set, the algorithm will chose such a position which fits `element`\n * the most inside visible viewport.\n *\n * @member {Boolean} #fitInViewport\n */\n\n/**\n * An object describing a position in `position: absolute` coordinate\n * system, along with position name.\n *\n * @typedef {Object} module:utils/dom/position~Position\n *\n * @property {Number} top Top position offset.\n * @property {Number} left Left position offset.\n * @property {String} name Name of the position.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/position.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/tounit\n */\n\n/**\n * Returns a helper function, which adds a desired trailing\n * `unit` to the passed value.\n *\n * @param {String} unit An unit like \"px\" or \"em\".\n * @returns {module:utils/dom/tounit~helper}\n */\nexport default function toUnit( unit ) {\n\t/**\n\t * A function, which adds a predefined trailing `unit`\n\t * to the passed `value`.\n\t *\n\t * @function helper\n \t * @param {*} value A value to be given the unit.\n \t * @returns {String} A value with the trailing unit.\n\t */\n\treturn value => value + unit;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/dom/tounit.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/panel/balloon/balloonpanelview\n */\n\nimport View from '../../view';\nimport { getOptimalPosition } from '@ckeditor/ckeditor5-utils/src/dom/position';\nimport isRange from '@ckeditor/ckeditor5-utils/src/dom/isrange';\nimport isElement from '@ckeditor/ckeditor5-utils/src/lib/lodash/isElement';\nimport toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';\nimport global from '@ckeditor/ckeditor5-utils/src/dom/global';\n\nconst toPx = toUnit( 'px' );\nconst defaultLimiterElement = global.document.body;\n\n/**\n * The balloon panel view class.\n *\n * A floating container which can\n * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#pin pin} to any\n * {@link module:utils/dom/position~Options#target target} in DOM and remain in that position\n * e.g. when the web page is scrolled.\n *\n * The balloon panel can be used to display contextual, non-blocking UI like forms, toolbars and\n * the like in its {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#content} view\n * collection.\n *\n * There is a number of {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}\n * that the balloon can use, automatically switching from one to another when the viewport space becomes\n * scarce to keep the balloon visible to the user as long as it is possible. The balloon will also\n * accept any custom position set provided by the user compatible with the\n * {@link module:utils/dom/position~Options options}.\n *\n *\t\tconst panel = new BalloonPanelView( locale );\n *\t\tconst childView = new ChildView();\n *\t\tconst positions = BalloonPanelView.defaultPositions;\n *\n *\t\tpanel.render();\n *\n *\t\t// Add a child view to the panel's content collection.\n *\t\tpanel.content.add( childView );\n *\n *\t\t// Start pinning the panel to an element with the \"target\" id DOM.\n *\t\t// The balloon will remain pinned until unpin() is called.\n *\t\tpanel.pin( {\n *\t\t\ttarget: document.querySelector( '#target' ),\n *\t\t\tpositions: [\n *\t\t\t\tpositions.northArrowSouth,\n *\t\t\t\tpositions.southArrowNorth\n *\t\t\t]\n *\t\t} );\n *\n * @extends module:ui/view~View\n */\nexport default class BalloonPanelView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * The absolute top position of the balloon panel in pixels.\n\t\t *\n\t\t * @observable\n\t\t * @default 0\n\t\t * @member {Number} #top\n\t\t */\n\t\tthis.set( 'top', 0 );\n\n\t\t/**\n\t\t * The absolute left position of the balloon panel in pixels.\n\t\t *\n\t\t * @observable\n\t\t * @default 0\n\t\t * @member {Number} #left\n\t\t */\n\t\tthis.set( 'left', 0 );\n\n\t\t/**\n\t\t * Balloon panel's current position. The position name is reflected in the CSS class set\n\t\t * to the balloon, i.e. `.ck-balloon-panel_arrow_nw` for \"arrow_nw\" position. The class\n\t\t * controls the minor aspects of the balloon's visual appearance like placement\n\t\t * of an {@link #withArrow arrow}. To support a new position, an additional CSS must be created.\n\t\t *\n\t\t * Default position names correspond with\n\t\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t\t *\n\t\t * See the {@link #attachTo} and {@link #pin} methods to learn about custom balloon positions.\n\t\t *\n\t\t * @observable\n\t\t * @default 'arrow_nw'\n\t\t * @member {'arrow_nw'|'arrow_ne'|'arrow_sw'|'arrow_se'} #position\n\t\t */\n\t\tthis.set( 'position', 'arrow_nw' );\n\n\t\t/**\n\t\t * Controls whether the balloon panel is visible or not.\n\t\t *\n\t\t * @observable\n\t\t * @default false\n\t\t * @member {Boolean} #isVisible\n\t\t */\n\t\tthis.set( 'isVisible', false );\n\n\t\t/**\n\t\t * Controls whether the balloon panel has an arrow. The presence of the arrow\n\t\t * is reflected in `ck-balloon-panel_with-arrow` CSS class.\n\t\t *\n\t\t * @observable\n\t\t * @default true\n\t\t * @member {Boolean} #withArrow\n\t\t */\n\t\tthis.set( 'withArrow', true );\n\n\t\t/**\n\t\t * An additional CSS class added to the {@link #element}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #className\n\t\t */\n\t\tthis.set( 'className' );\n\n\t\t/**\n\t\t * A callback that starts pining the panel when {@link #isVisible} gets\n\t\t * `true`. Used by {@link #pin}.\n\t\t *\n\t\t * @private\n\t\t * @member {Function} #_pinWhenIsVisibleCallback\n\t\t */\n\n\t\t/**\n\t\t * Collection of the child views which creates balloon panel contents.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.content = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-balloon-panel',\n\t\t\t\t\tbind.to( 'position', value => `ck-balloon-panel_${ value }` ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-balloon-panel_visible' ),\n\t\t\t\t\tbind.if( 'withArrow', 'ck-balloon-panel_with-arrow' ),\n\t\t\t\t\tbind.to( 'className' )\n\t\t\t\t],\n\n\t\t\t\tstyle: {\n\t\t\t\t\ttop: bind.to( 'top', toPx ),\n\t\t\t\t\tleft: bind.to( 'left', toPx )\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tchildren: this.content\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the panel.\n\t *\n\t * See {@link #isVisible}.\n\t */\n\tshow() {\n\t\tthis.isVisible = true;\n\t}\n\n\t/**\n\t * Hides the panel.\n\t *\n\t * See {@link #isVisible}.\n\t */\n\thide() {\n\t\tthis.isVisible = false;\n\t}\n\n\t/**\n\t * Attaches the panel to a specified {@link module:utils/dom/position~Options#target} with a\n\t * smart positioning heuristics that choses from available positions to make sure the panel\n\t * is visible to the user i.e. within the limits of the viewport.\n\t *\n\t * This method accepts configuration {@link module:utils/dom/position~Options options}\n\t * to set the `target`, optional `limiter` and `positions` the balloon should chose from.\n\t *\n\t *\t\tconst panel = new BalloonPanelView( locale );\n\t *\t\tconst positions = BalloonPanelView.defaultPositions;\n\t *\n\t *\t\tpanel.render();\n\t *\n\t *\t\t// Attach the panel to an element with the \"target\" id DOM.\n\t *\t\tpanel.attachTo( {\n\t *\t\t\ttarget: document.querySelector( '#target' ),\n\t *\t\t\tpositions: [\n\t *\t\t\t\tpositions.northArrowSouth,\n\t *\t\t\t\tpositions.southArrowNorth\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t * **Note**: Attaching the panel will also automatically {@link #show} it.\n\t *\n\t * **Note**: An attached panel will not follow its target when the window is scrolled or resized.\n\t * See the {@link #pin} method for more permanent positioning strategy.\n\t *\n\t * @param {module:utils/dom/position~Options} options Positioning options compatible with\n\t * {@link module:utils/dom/position~getOptimalPosition}. Default `positions` array is\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t */\n\tattachTo( options ) {\n\t\tthis.show();\n\n\t\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\t\tconst positionOptions = Object.assign( {}, {\n\t\t\telement: this.element,\n\t\t\tpositions: [\n\t\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\t\tdefaultPositions.southArrowNorthEast,\n\t\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\t\tdefaultPositions.northArrowSouthEast\n\t\t\t],\n\t\t\tlimiter: defaultLimiterElement,\n\t\t\tfitInViewport: true\n\t\t}, options );\n\n\t\tconst { top, left, name: position } = getOptimalPosition( positionOptions );\n\n\t\tObject.assign( this, { top, left, position } );\n\t}\n\n\t/**\n\t * Works the same way as the {@link #attachTo} method except that the position of the panel is\n\t * continuously updated when:\n\t *\n\t * * any ancestor of the {@link module:utils/dom/position~Options#target}\n\t * or {@link module:utils/dom/position~Options#limiter} is scrolled,\n\t * * the browser window gets resized or scrolled.\n\t *\n\t * Thanks to that, the panel always sticks to the {@link module:utils/dom/position~Options#target},\n\t * immune to the changing environment.\n\t *\n\t *\t\tconst panel = new BalloonPanelView( locale );\n\t *\t\tconst positions = BalloonPanelView.defaultPositions;\n\t *\n\t *\t\tpanel.render();\n\t *\n\t *\t\t// Pin the panel to an element with the \"target\" id DOM.\n\t *\t\tpanel.pin( {\n\t *\t\t\ttarget: document.querySelector( '#target' ),\n\t *\t\t\tpositions: [\n\t *\t\t\t\tpositions.northArrowSouth,\n\t *\t\t\t\tpositions.southArrowNorth\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t * To leave the pinned state, use the {@link #unpin} method.\n\t *\n\t * **Note**: Pinning the panel will also automatically {@link #show} it.\n\t *\n\t * @param {module:utils/dom/position~Options} options Positioning options compatible with\n\t * {@link module:utils/dom/position~getOptimalPosition}. Default `positions` array is\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t */\n\tpin( options ) {\n\t\tthis.unpin();\n\n\t\tthis._pinWhenIsVisibleCallback = () => {\n\t\t\tif ( this.isVisible ) {\n\t\t\t\tthis._startPinning( options );\n\t\t\t} else {\n\t\t\t\tthis._stopPinning();\n\t\t\t}\n\t\t};\n\n\t\tthis._startPinning( options );\n\n\t\t// Control the state of the listeners depending on whether the panel is visible\n\t\t// or not.\n\t\t// TODO: Use on() (https://github.com/ckeditor/ckeditor5-utils/issues/144).\n\t\tthis.listenTo( this, 'change:isVisible', this._pinWhenIsVisibleCallback );\n\t}\n\n\t/**\n\t * Stops pinning the panel, as set up by {@link #pin}.\n\t */\n\tunpin() {\n\t\tif ( this._pinWhenIsVisibleCallback ) {\n\t\t\t// Deactivate listeners attached by pin().\n\t\t\tthis._stopPinning();\n\n\t\t\t// Deactivate the panel pin() control logic.\n\t\t\t// TODO: Use off() (https://github.com/ckeditor/ckeditor5-utils/issues/144).\n\t\t\tthis.stopListening( this, 'change:isVisible', this._pinWhenIsVisibleCallback );\n\n\t\t\tthis._pinWhenIsVisibleCallback = null;\n\n\t\t\tthis.hide();\n\t\t}\n\t}\n\n\t/**\n\t * Starts managing the pinned state of the panel. See {@link #pin}.\n\t *\n\t * @private\n\t * @param {module:utils/dom/position~Options} options Positioning options compatible with\n\t * {@link module:utils/dom/position~getOptimalPosition}.\n\t */\n\t_startPinning( options ) {\n\t\tthis.attachTo( options );\n\n\t\tconst targetElement = getDomElement( options.target );\n\t\tconst limiterElement = options.limiter ? getDomElement( options.limiter ) : defaultLimiterElement;\n\n\t\t// Then we need to listen on scroll event of eny element in the document.\n\t\tthis.listenTo( global.document, 'scroll', ( evt, domEvt ) => {\n\t\t\tconst scrollTarget = domEvt.target;\n\n\t\t\t// The position needs to be updated if the positioning target is within the scrolled element.\n\t\t\tconst isWithinScrollTarget = targetElement && scrollTarget.contains( targetElement );\n\n\t\t\t// The position needs to be updated if the positioning limiter is within the scrolled element.\n\t\t\tconst isLimiterWithinScrollTarget = limiterElement && scrollTarget.contains( limiterElement );\n\n\t\t\t// The positioning target and/or limiter can be a Rect, object etc..\n\t\t\t// There's no way to optimize the listener then.\n\t\t\tif ( isWithinScrollTarget || isLimiterWithinScrollTarget || !targetElement || !limiterElement ) {\n\t\t\t\tthis.attachTo( options );\n\t\t\t}\n\t\t}, { useCapture: true } );\n\n\t\t// We need to listen on window resize event and update position.\n\t\tthis.listenTo( global.window, 'resize', () => {\n\t\t\tthis.attachTo( options );\n\t\t} );\n\t}\n\n\t/**\n\t * Stops managing the pinned state of the panel. See {@link #pin}.\n\t *\n\t * @private\n\t */\n\t_stopPinning() {\n\t\tthis.stopListening( global.document, 'scroll' );\n\t\tthis.stopListening( global.window, 'resize' );\n\t}\n}\n\n// Returns the DOM element for given object or null, if there's none,\n// e.g. when passed object is a Rect instance or so.\n//\n// @private\n// @param {*} object\n// @returns {HTMLElement|null}\nfunction getDomElement( object ) {\n\tif ( isElement( object ) ) {\n\t\treturn object;\n\t}\n\n\tif ( isRange( object ) ) {\n\t\treturn object.commonAncestorContainer;\n\t}\n\n\tif ( typeof object == 'function' ) {\n\t\treturn getDomElement( object() );\n\t}\n\n\treturn null;\n}\n\n/**\n * A horizontal offset of the arrow tip from the edge of the balloon. Controlled by CSS.\n *\n *\t\t +-----|---------...\n *\t\t | |\n *\t\t | |\n *\t\t | |\n *\t\t | |\n *\t\t +--+ | +------...\n *\t\t \\ | /\n *\t\t \\|/\n *\t >|-----|<---------------- horizontal offset\n *\n * @default 30\n * @member {Number} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowHorizontalOffset\n */\nBalloonPanelView.arrowHorizontalOffset = 30;\n\n/**\n * A vertical offset of the arrow from the edge of the balloon. Controlled by CSS.\n *\n *\t\t +-------------...\n *\t\t |\n *\t\t |\n *\t\t | /-- vertical offset\n *\t\t | V\n *\t\t +--+ +-----... ---------\n *\t\t \\ / |\n *\t\t \\/ |\n *\t\t-------------------------------\n *\t\t ^\n *\n * @default 15\n * @member {Number} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowVerticalOffset\n */\nBalloonPanelView.arrowVerticalOffset = 15;\n\n/**\n * A default set of positioning functions used by the balloon panel view\n * when attaching using {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo} method.\n *\n * The available positioning functions are as follow:\n *\n * **North**\n *\n * * `northArrowSouth`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northArrowSouthEast`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northArrowSouthWest`\n *\n * \t\t +-----------------+\n * \t\t | Balloon |\n * \t\t +-----------------+\n * \t\t V\n * \t\t[ Target ]\n *\n * **North west**\n *\n * * `northWestArrowSouth`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northWestArrowSouthWest`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northWestArrowSouthEast`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * **North east**\n *\n * * `northEastArrowSouth`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t[ Target ]\n *\n * * `northEastArrowSouthEast`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northEastArrowSouthWest`\n *\n * \t\t +-----------------+\n * \t\t | Balloon |\n * \t\t +-----------------+\n * \t\t V\n * \t\t[ Target ]\n *\n * **South**\n *\n * * `southArrowNorth`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southArrowNorthEast`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southArrowNorthWest`\n *\n *\t\t[ Target ]\n *\t\t ^\n *\t\t +-----------------+\n *\t\t | Balloon |\n *\t\t +-----------------+\n *\n * **South west**\n *\n * * `southWestArrowNorth`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southWestArrowNorthWest`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southWestArrowNorthEast`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * **South east**\n *\n * * `southEastArrowNorth`\n *\n *\t\t[ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southEastArrowNorthEast`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southEastArrowNorthWest`\n *\n *\t\t[ Target ]\n *\t\t ^\n *\t\t +-----------------+\n *\t\t | Balloon |\n *\t\t +-----------------+\n *\n * See {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo}.\n *\n * Positioning functions must be compatible with {@link module:utils/dom/position~Position}.\n *\n * The name that position function returns will be reflected in balloon panel's class that\n * controls the placement of the \"arrow\". See {@link #position} to learn more.\n *\n * @member {Object} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions\n */\nBalloonPanelView.defaultPositions = {\n\t// ------- North\n\n\tnorthArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n\t\tname: 'arrow_s'\n\t} ),\n\n\tnorthArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_se'\n\t} ),\n\n\tnorthArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_sw'\n\t} ),\n\n\t// ------- North west\n\n\tnorthWestArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - balloonRect.width / 2,\n\t\tname: 'arrow_s'\n\t} ),\n\n\tnorthWestArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_sw'\n\t} ),\n\n\tnorthWestArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_se'\n\t} ),\n\n\t// ------- North east\n\n\tnorthEastArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - balloonRect.width / 2,\n\t\tname: 'arrow_s'\n\t} ),\n\n\tnorthEastArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_se'\n\t} ),\n\n\tnorthEastArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_sw'\n\t} ),\n\n\t// ------- South\n\n\tsouthArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n\t\tname: 'arrow_n'\n\t} ),\n\n\tsouthArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_ne'\n\t} ),\n\n\tsouthArrowNorthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_nw'\n\t} ),\n\n\t// ------- South west\n\n\tsouthWestArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - balloonRect.width / 2,\n\t\tname: 'arrow_n'\n\t} ),\n\n\tsouthWestArrowNorthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_nw'\n\t} ),\n\n\tsouthWestArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_ne'\n\t} ),\n\n\t// ------- South east\n\n\tsouthEastArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - balloonRect.width / 2,\n\t\tname: 'arrow_n'\n\t} ),\n\n\tsouthEastArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_ne'\n\t} ),\n\n\tsouthEastArrowNorthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_nw'\n\t} ),\n};\n\n// Returns the top coordinate for positions starting with `north*`.\n//\n// @private\n// @param {utils/dom/rect~Rect} targetRect A rect of the target.\n// @param {utils/dom/rect~Rect} elementRect A rect of the balloon.\n// @returns {Number}\nfunction getNorthTop( targetRect, balloonRect ) {\n\treturn targetRect.top - balloonRect.height - BalloonPanelView.arrowVerticalOffset;\n}\n\n// Returns the top coordinate for positions starting with `south*`.\n//\n// @private\n// @param {utils/dom/rect~Rect} targetRect A rect of the target.\n// @param {utils/dom/rect~Rect} elementRect A rect of the balloon.\n// @returns {Number}\nfunction getSouthTop( targetRect ) {\n\treturn targetRect.bottom + BalloonPanelView.arrowVerticalOffset;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/panel/balloon/balloonpanelview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/first\n */\n\n/**\n * Returns first item of the given `iterable`.\n *\n * @param {Iterable.<*>} iterable\n * @returns {*}\n */\nexport default function first( iterable ) {\n\tconst iteratorItem = iterable.next();\n\n\tif ( iteratorItem.done ) {\n\t\treturn null;\n\t}\n\n\treturn iteratorItem.value;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/first.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/panel/balloon/contextualballoon\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport BalloonPanelView from './balloonpanelview';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * Provides the common contextual balloon panel for the editor.\n *\n * This plugin allows reusing a single {module:ui/panel/balloon/balloonpanelview~BalloonPanelView} instance\n * to display multiple contextual balloon panels in the editor.\n *\n * Child views of such a panel are stored in the stack and the last one in the stack is visible. When the\n * visible view is removed from the stack, the previous view becomes visible, etc. If there are no more\n * views in the stack, the balloon panel will hide.\n *\n * It simplifies managing the views and helps\n * avoid the unnecessary complexity of handling multiple {module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n * instances in the editor.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ContextualBalloon extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ContextualBalloon';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\t/**\n\t\t * The common balloon panel view.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/panel/balloon/balloonpanelview~BalloonPanelView} #view\n\t\t */\n\t\tthis.view = new BalloonPanelView();\n\n\t\t/**\n\t\t * The {@link module:utils/dom/position~Options#limiter position limiter}\n\t\t * for the {@link #view}, used when no `limiter` has been passed into {@link #add}\n\t\t * or {@link #updatePosition}.\n\t\t *\n\t\t * By default, a function, which obtains the farthest DOM\n\t\t * {@link module:engine/view/rooteditableelement~RootEditableElement}\n\t\t * of the {@link module:engine/view/document~Document#selection}.\n\t\t *\n\t\t * @member {module:utils/dom/position~Options#limiter} #positionLimiter\n\t\t */\n\t\tthis.positionLimiter = () => {\n\t\t\tconst view = this.editor.editing.view;\n\t\t\tconst editableElement = view.selection.editableElement;\n\n\t\t\tif ( editableElement ) {\n\t\t\t\treturn view.domConverter.mapViewToDom( editableElement.root );\n\t\t\t}\n\n\t\t\treturn null;\n\t\t};\n\n\t\t/**\n\t\t * Stack of the views injected into the balloon. Last one in the stack is displayed\n\t\t * as a content of {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon#view}.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} #_stack\n\t\t */\n\t\tthis._stack = new Map();\n\n\t\t// Add balloon panel view to editor `body` collection and wait until view will be ready.\n\t\tthis.editor.ui.view.body.add( this.view );\n\n\t\t// Editor should be focused when contextual balloon is focused.\n\t\tthis.editor.ui.focusTracker.add( this.view.element );\n\t}\n\n\t/**\n\t * Returns the currently visible view or `null` when there are no\n\t * views in the stack.\n\t *\n\t * @returns {module:ui/view~View|null}\n\t */\n\tget visibleView() {\n\t\tconst item = this._stack.get( this.view.content.get( 0 ) );\n\n\t\treturn item ? item.view : null;\n\t}\n\n\t/**\n\t * Returns `true` when the given view is in the stack. Otherwise returns `false`.\n\t *\n\t * @param {module:ui/view~View} view\n\t * @returns {Boolean}\n\t */\n\thasView( view ) {\n\t\treturn this._stack.has( view );\n\t}\n\n\t/**\n\t * Adds a new view to the stack and makes it visible.\n\t *\n\t * @param {Object} data Configuration of the view.\n\t * @param {module:ui/view~View} [data.view] Content of the balloon.\n\t * @param {module:utils/dom/position~Options} [data.position] Positioning options.\n\t * @param {String} [data.balloonClassName] Additional css class for {@link #view} added when given view is visible.\n\t */\n\tadd( data ) {\n\t\tif ( this.hasView( data.view ) ) {\n\t\t\t/**\n\t\t\t * Trying to add configuration of the same view more than once.\n\t\t\t *\n\t\t\t * @error contextualballoon-add-view-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'contextualballoon-add-view-exist: Cannot add configuration of the same view twice.' );\n\t\t}\n\n\t\t// When adding view to the not empty balloon.\n\t\tif ( this.visibleView ) {\n\t\t\t// Remove displayed content from the view.\n\t\t\tthis.view.content.remove( this.visibleView );\n\t\t}\n\n\t\t// Add new view to the stack.\n\t\tthis._stack.set( data.view, data );\n\n\t\t// And display it.\n\t\tthis._show( data );\n\t}\n\n\t/**\n\t * Removes the given view from the stack. If the removed view was visible,\n\t * then the view preceding it in the stack will become visible instead.\n\t * When there is no view in the stack then balloon will hide.\n\t *\n\t * @param {module:ui/view~View} view A view to be removed from the balloon.\n\t */\n\tremove( view ) {\n\t\tif ( !this.hasView( view ) ) {\n\t\t\t/**\n\t\t\t * Trying to remove configuration of the view not defined in the stack.\n\t\t\t *\n\t\t\t * @error contextualballoon-remove-view-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'contextualballoon-remove-view-not-exist: Cannot remove configuration of not existing view.' );\n\t\t}\n\n\t\t// When visible view is being removed.\n\t\tif ( this.visibleView === view ) {\n\t\t\t// We need to remove it from the view content.\n\t\t\tthis.view.content.remove( view );\n\n\t\t\t// And then remove from the stack.\n\t\t\tthis._stack.delete( view );\n\n\t\t\t// Next we need to check if there is other view in stack to show.\n\t\t\tconst last = Array.from( this._stack.values() ).pop();\n\n\t\t\t// If it is some other view.\n\t\t\tif ( last ) {\n\t\t\t\t// Just show it.\n\t\t\t\tthis._show( last );\n\t\t\t} else {\n\t\t\t\t// Hide the balloon panel.\n\t\t\t\tthis.view.hide();\n\t\t\t}\n\t\t} else {\n\t\t\t// Just remove given view from the stack.\n\t\t\tthis._stack.delete( view );\n\t\t}\n\t}\n\n\t/**\n\t * Updates the position of the balloon using position data of the first visible view in the stack.\n\t * When new position data is given then position data of currently visible panel will be updated.\n\t *\n\t * @param {module:utils/dom/position~Options} [position] position options.\n\t */\n\tupdatePosition( position ) {\n\t\tif ( position ) {\n\t\t\tthis._stack.get( this.visibleView ).position = position;\n\t\t}\n\n\t\tthis.view.pin( this._getBalloonPosition() );\n\t}\n\n\t/**\n\t * Sets the view as a content of the balloon and attaches balloon using position\n\t * options of the first view.\n\t *\n\t * @private\n\t * @param {Object} data Configuration.\n\t * @param {module:ui/view~View} [data.view] View to show in the balloon.\n\t * @param {String} [data.balloonClassName=''] Additional class name which will added to the {#_balloon} view.\n\t */\n\t_show( { view, balloonClassName = '' } ) {\n\t\tthis.view.className = balloonClassName;\n\n\t\tthis.view.content.add( view );\n\t\tthis.view.pin( this._getBalloonPosition() );\n\t}\n\n\t/**\n\t * Returns position options of the first view in the stack.\n\t * This keeps the balloon in the same position when view is changed.\n\t *\n\t * @private\n\t * @returns {module:utils/dom/position~Options}\n\t */\n\t_getBalloonPosition() {\n\t\tlet position = first( this._stack.values() ).position;\n\n\t\t// Use the default limiter if none has been specified.\n\t\tif ( position && !position.limiter ) {\n\t\t\t// Don't modify the original options object.\n\t\t\tposition = Object.assign( {}, position, {\n\t\t\t\tlimiter: this.positionLimiter\n\t\t\t} );\n\t\t}\n\n\t\treturn position;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/panel/balloon/contextualballoon.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/focuscycler\n */\n\nimport global from '@ckeditor/ckeditor5-utils/src/dom/global';\n\n/**\n * A utility class that helps cycling over focusable {@link module:ui/view~View views} in a\n * {@link module:ui/viewcollection~ViewCollection} when the focus is tracked by the\n * {@link module:utils/focustracker~FocusTracker} instance. It helps implementing keyboard\n * navigation in HTML forms, toolbars, lists and the like.\n *\n * To work properly it requires:\n * * a collection of focusable (HTML `tabindex` attribute) views that implement the `focus()` method,\n * * an associated focus tracker to determine which view is focused.\n *\n * A simple cycler setup can look like this:\n *\n *\t\tconst focusables = new ViewCollection();\n *\t\tconst focusTracker = new FocusTracker();\n *\n *\t\t// Add focusable views to the focus tracker.\n *\t\tfocusTracker.add( ... );\n *\n * Then, the cycler can be used manually:\n *\n *\t\tconst cycler = new FocusCycler( { focusables, focusTracker } );\n *\n *\t\t// Will focus the first focusable view in #focusables.\n *\t\tcycler.focusFirst();\n *\n *\t\t// Will log the next focusable item in #focusables.\n *\t\tconsole.log( cycler.next );\n *\n * Alternatively, it can work side by side with the {@link module:utils/keystrokehandler~KeystrokeHandler}:\n *\n *\t\tconst keystrokeHandler = new KeystrokeHandler();\n *\n *\t\t// Activate the keystroke handler.\n *\t\tkeystrokeHandler.listenTo( sourceOfEvents );\n *\n *\t\tconst cycler = new FocusCycler( {\n *\t\t\tfocusables, focusTracker, keystrokeHandler,\n *\t\t\tactions: {\n *\t\t\t\t// When arrowup of arrowleft is detected by the #keystrokeHandler,\n *\t\t\t\t// focusPrevious() will be called on the cycler.\n *\t\t\t\tfocusPrevious: [ 'arrowup', 'arrowleft' ],\n *\t\t\t}\n *\t\t} );\n */\nexport default class FocusCycler {\n\t/**\n\t * Creates an instance of the focus cycler utility.\n\t *\n\t * @param {Object} options Configuration options.\n\t * @param {module:utils/collection~Collection|Object} options.focusables\n\t * @param {module:utils/focustracker~FocusTracker} options.focusTracker\n\t * @param {module:utils/keystrokehandler~KeystrokeHandler} [options.keystrokeHandler]\n\t * @param {Object} [options.actions]\n\t */\n\tconstructor( options ) {\n\t\tObject.assign( this, options );\n\n\t\t/**\n\t\t * A {@link module:ui/view~View view} collection that the cycler operates on.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/collection~Collection} #focusables\n\t\t */\n\n\t\t/**\n\t\t * A focus tracker instance that the cycler uses to determine the current focus\n\t\t * state in {@link #focusables}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker} #focusTracker\n\t\t */\n\n\t\t/**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}\n\t\t * which can respond to certain keystrokes and cycle the focus.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler} #keystrokeHandler\n\t\t */\n\n\t\t/**\n\t\t * Actions that the cycler can take when a keystroke is pressed. Requires\n\t\t * `options.keystrokeHandler` to be passed and working. When an action is\n\t\t * performed, `preventDefault` and `stopPropagation` will be called on the event\n\t\t * the keystroke fired in the DOM.\n\t\t *\n\t\t *\t\tactions: {\n\t\t *\t\t\t// Will call #focusPrevious() when arrowleft or arrowup is pressed.\n\t\t *\t\t\tfocusPrevious: [ 'arrowleft', 'arrowup' ],\n\t\t *\n\t\t *\t\t\t// Will call #focusNext() when arrowdown is pressed.\n\t\t *\t\t\tfocusNext: 'arrowdown'\n\t\t *\t\t}\n\t\t *\n\t\t * @readonly\n\t\t * @member {Object} #actions\n\t\t */\n\n\t\tif ( options.actions && options.keystrokeHandler ) {\n\t\t\tfor ( const methodName in options.actions ) {\n\t\t\t\tlet actions = options.actions[ methodName ];\n\n\t\t\t\tif ( typeof actions == 'string' ) {\n\t\t\t\t\tactions = [ actions ];\n\t\t\t\t}\n\n\t\t\t\tfor ( const keystroke of actions ) {\n\t\t\t\t\toptions.keystrokeHandler.set( keystroke, ( data, cancel ) => {\n\t\t\t\t\t\tthis[ methodName ]();\n\t\t\t\t\t\tcancel();\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns the first focusable view in {@link #focusables}.\n\t * Returns `null` if there is none.\n\t *\n\t * @readonly\n\t * @member {module:ui/view~View|null} #first\n\t */\n\tget first() {\n\t\treturn this.focusables.find( isFocusable ) || null;\n\t}\n\n\t/**\n\t * Returns the last focusable view in {@link #focusables}.\n\t * Returns `null` if there is none.\n\t *\n\t * @readonly\n\t * @member {module:ui/view~View|null} #last\n\t */\n\tget last() {\n\t\treturn this.focusables.filter( isFocusable ).slice( -1 )[ 0 ] || null;\n\t}\n\n\t/**\n\t * Returns the next focusable view in {@link #focusables} based on {@link #current}.\n\t * Returns `null` if there is none.\n\t *\n\t * @readonly\n\t * @member {module:ui/view~View|null} #next\n\t */\n\tget next() {\n\t\treturn this._getFocusableItem( 1 );\n\t}\n\n\t/**\n\t * Returns the previous focusable view in {@link #focusables} based on {@link #current}.\n\t * Returns `null` if there is none.\n\t *\n\t * @readonly\n\t * @member {module:ui/view~View|null} #previous\n\t */\n\tget previous() {\n\t\treturn this._getFocusableItem( -1 );\n\t}\n\n\t/**\n\t * An index of the view in the {@link #focusables} which is focused according\n\t * to {@link #focusTracker}. Returns `null` when there is no such view.\n\t *\n\t * @readonly\n\t * @member {Number|null} #current\n\t */\n\tget current() {\n\t\tlet index = null;\n\n\t\t// There's no focused view in the focusables.\n\t\tif ( this.focusTracker.focusedElement === null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.focusables.find( ( view, viewIndex ) => {\n\t\t\tconst focused = view.element === this.focusTracker.focusedElement;\n\n\t\t\tif ( focused ) {\n\t\t\t\tindex = viewIndex;\n\t\t\t}\n\n\t\t\treturn focused;\n\t\t} );\n\n\t\treturn index;\n\t}\n\n\t/**\n\t * Focuses the {@link #first} item in {@link #focusables}.\n\t */\n\tfocusFirst() {\n\t\tthis._focus( this.first );\n\t}\n\n\t/**\n\t * Focuses the {@link #last} item in {@link #focusables}.\n\t */\n\tfocusLast() {\n\t\tthis._focus( this.last );\n\t}\n\n\t/**\n\t * Focuses the {@link #next} item in {@link #focusables}.\n\t */\n\tfocusNext() {\n\t\tthis._focus( this.next );\n\t}\n\n\t/**\n\t * Focuses the {@link #previous} item in {@link #focusables}.\n\t */\n\tfocusPrevious() {\n\t\tthis._focus( this.previous );\n\t}\n\n\t/**\n\t * Focuses the given view if it exists.\n\t *\n\t * @protected\n\t * @param {module:ui/view~View} view\n\t */\n\t_focus( view ) {\n\t\tif ( view ) {\n\t\t\tview.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Returns the next or previous focusable view in {@link #focusables} with respect\n\t * to {@link #current}.\n\t *\n\t * @protected\n\t * @param {Number} step Either `1` for checking forward from {@link #current} or\n\t * `-1` for checking backwards.\n\t * @returns {module:ui/view~View|null}\n\t */\n\t_getFocusableItem( step ) {\n\t\t// Cache for speed.\n\t\tconst current = this.current;\n\t\tconst collectionLength = this.focusables.length;\n\n\t\tif ( !collectionLength ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Start from the beginning if no view is focused.\n\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/206\n\t\tif ( current === null ) {\n\t\t\treturn this[ step === 1 ? 'first' : 'last' ];\n\t\t}\n\n\t\t// Cycle in both directions.\n\t\tlet index = ( current + collectionLength + step ) % collectionLength;\n\n\t\tdo {\n\t\t\tconst view = this.focusables.get( index );\n\n\t\t\t// TODO: Check if view is visible.\n\t\t\tif ( isFocusable( view ) ) {\n\t\t\t\treturn view;\n\t\t\t}\n\n\t\t\t// Cycle in both directions.\n\t\t\tindex = ( index + collectionLength + step ) % collectionLength;\n\t\t} while ( index !== current );\n\n\t\treturn null;\n\t}\n}\n\n// Checks whether a view is focusable.\n//\n// @private\n// @param {module:ui/view~View} view A view to be checked.\n// @returns {Boolean}\nfunction isFocusable( view ) {\n\treturn !!( view.focus && global.window.getComputedStyle( view.element ).display != 'none' );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/focuscycler.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/toolbarseparatorview\n */\n\nimport View from '../view';\n\n/**\n * The toolbar separator view class.\n *\n * @extends module:ui/view~View\n */\nexport default class ToolbarSeparatorView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-toolbar__separator'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/toolbar/toolbarseparatorview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/bindings/preventdefault\n */\n\n/**\n * A helper which executes a native `Event.preventDefault()` if the target of an event equals the\n * {@link module:ui/view~View#element element of the view}. It shortens the definition of a\n * {@link module:ui/view~View#template template}.\n *\n *\t\t// In a class extending View.\n *\t\timport preventDefault from '@ckeditor/ckeditor5-ui/src/bindings/preventdefault';\n *\n *\t\t// ...\n *\n *\t\tthis.setTemplate( {\n *\t\t\ttag: 'div',\n *\n *\t\t\ton: {\n *\t\t\t\t// Prevent the default mousedown action on this view.\n *\t\t\t\tmousedown: preventDefault( this )\n *\t\t\t}\n *\t\t} );\n *\n * @param {module:ui/view~View} view View instance that defines the template.\n * @returns {module:ui/template~TemplateToBinding}\n */\nexport default function preventDefault( view ) {\n\treturn view.bindTemplate.to( evt => {\n\t\tif ( evt.target === view.element ) {\n\t\t\tevt.preventDefault();\n\t\t}\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/bindings/preventdefault.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/toolbarview\n */\n\nimport View from '../view';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '../focuscycler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\nimport ToolbarSeparatorView from './toolbarseparatorview';\nimport preventDefault from '../bindings/preventdefault.js';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\n/**\n * The toolbar view class.\n *\n * @extends module:ui/view~View\n */\nexport default class ToolbarView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * Collection of the toolbar items (like buttons).\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.items = this.createCollection();\n\n\t\t/**\n\t\t * Tracks information about DOM focus in the list.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\t/**\n\t\t * Helps cycling over focusable {@link #items} in the toolbar.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.items,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate toolbar items backwards using the arrow[left,up] keys.\n\t\t\t\tfocusPrevious: [ 'arrowleft', 'arrowup' ],\n\n\t\t\t\t// Navigate toolbar items forwards using the arrow[right,down] keys.\n\t\t\t\tfocusNext: [ 'arrowright', 'arrowdown' ]\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-toolbar'\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.items,\n\n\t\t\ton: {\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/206\n\t\t\t\tmousedown: preventDefault( this )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Items added before rendering should be known to the #focusTracker.\n\t\tfor ( const item of this.items ) {\n\t\t\tthis.focusTracker.add( item.element );\n\t\t}\n\n\t\tthis.items.on( 'add', ( evt, item ) => {\n\t\t\tthis.focusTracker.add( item.element );\n\t\t} );\n\n\t\tthis.items.on( 'remove', ( evt, item ) => {\n\t\t\tthis.focusTracker.remove( item.element );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\t}\n\n\t/**\n\t * Focuses the first focusable in {@link #items}.\n\t */\n\tfocus() {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * A utility which expands a plain toolbar configuration into\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#items} using a given component factory.\n\t *\n\t * @param {Array.<String>} config The toolbar items config.\n\t * @param {module:ui/componentfactory~ComponentFactory} factory A factory producing toolbar items.\n\t */\n\tfillFromConfig( config, factory ) {\n\t\tconfig.map( name => {\n\t\t\tif ( name == '|' ) {\n\t\t\t\tthis.items.add( new ToolbarSeparatorView() );\n\t\t\t} else if ( factory.has( name ) ) {\n\t\t\t\tthis.items.add( factory.create( name ) );\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * There was a problem processing the configuration of the toolbar. The item with the given\n\t\t\t\t * name does not exist so it was omitted when rendering the toolbar.\n\t\t\t\t *\n\t\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t\t * to provide a toolbar item has not been loaded or there is a typo in the configuration.\n\t\t\t\t *\n\t\t\t\t * Make sure the plugin responsible for this toolbar item is loaded and the toolbar configuration\n\t\t\t\t * is correct, e.g. {@link module:basic-styles/bold~Bold} is loaded for the `'bold'` toolbar item.\n\t\t\t\t *\n\t\t\t\t * You can use the following snippet to retrieve all available toolbar items:\n\t\t\t\t *\n\t\t\t\t *\t\tArray.from( editor.ui.componentFactory.names );\n\t\t\t\t *\n\t\t\t\t * @error toolbarview-item-unavailable\n\t\t\t\t * @param {String} name The name of the component.\n\t\t\t\t */\n\t\t\t\tlog.warn(\n\t\t\t\t\t'toolbarview-item-unavailable: The requested toolbar item is unavailable.',\n\t\t\t\t\t{ name }\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\t}\n}\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/toolbar/toolbarview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/normalizetoolbarconfig\n */\n\n/**\n * Normalizes the toolbar configuration (`config.toolbar`), which:\n *\n * * may be defined as an `Array`:\n *\n * \t\ttoolbar: [ 'headings', 'bold', 'italic', 'link', ... ]\n *\n * * or an `Object`:\n *\n *\t\ttoolbar: {\n *\t\t\titems: [ 'headings', 'bold', 'italic', 'link', ... ],\n *\t\t\t...\n *\t\t}\n *\n * * or may not be defined at all (`undefined`)\n *\n * and returns it in the object form.\n *\n * @param {Array|Object|undefined} config The value of `config.toolbar`.\n * @returns {Object} A normalized toolbar config object.\n */\nexport default function normalizeToolbarConfig( config ) {\n\tif ( Array.isArray( config ) ) {\n\t\treturn {\n\t\t\titems: config\n\t\t};\n\t}\n\n\tif ( !config ) {\n\t\treturn {\n\t\t\titems: []\n\t\t};\n\t}\n\n\treturn Object.assign( {\n\t\titems: []\n\t}, config );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/toolbar/normalizetoolbarconfig.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/contextual/contextualtoolbar\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ContextualBalloon from '../../panel/balloon/contextualballoon';\nimport ToolbarView from '../toolbarview';\nimport BalloonPanelView from '../../panel/balloon/balloonpanelview.js';\nimport debounce from '@ckeditor/ckeditor5-utils/src/lib/lodash/debounce';\nimport Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';\nimport normalizeToolbarConfig from '../normalizetoolbarconfig';\n\n/**\n * The contextual toolbar.\n *\n * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ContextualToolbar extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ContextualToolbar';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t/**\n\t\t * The toolbar view displayed in the balloon.\n\t\t *\n\t\t * @member {module:ui/toolbar/toolbarview~ToolbarView}\n\t\t */\n\t\tthis.toolbarView = new ToolbarView( editor.locale );\n\n\t\tthis.toolbarView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-editor-toolbar',\n\t\t\t\t\t'ck-toolbar_floating'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\n\t\tthis.toolbarView.render();\n\n\t\t/**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n\t\tthis._balloon = editor.plugins.get( ContextualBalloon );\n\n\t\t/**\n\t\t * Fires {@link #event:_selectionChangeDebounced} event using `lodash#debounce`.\n\t\t *\n\t\t * This function is stored as a plugin property to make possible to cancel\n\t\t * trailing debounced invocation on destroy.\n\t\t *\n\t\t * @private\n\t\t * @member {Function}\n\t\t */\n\t\tthis._fireSelectionChangeDebounced = debounce( () => this.fire( '_selectionChangeDebounced' ), 200 );\n\n\t\t// Attach lifecycle actions.\n\t\tthis._handleSelectionChange();\n\t\tthis._handleFocusChange();\n\n\t\t// The appearance of the ContextualToolbar method is eventdriven.\n\t\t// It is possible to stop the #show event and this prevent the toolbar from showing up.\n\t\tthis.decorate( 'show' );\n\t}\n\n\t/**\n\t * Creates toolbar components based on given configuration.\n\t * This needs to be done when all plugins are ready.\n\t *\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst config = normalizeToolbarConfig( this.editor.config.get( 'contextualToolbar' ) );\n\t\tconst factory = this.editor.ui.componentFactory;\n\n\t\tthis.toolbarView.fillFromConfig( config.items, factory );\n\t}\n\n\t/**\n\t * Handles the editor focus change and hides the toolbar if it's needed.\n\t *\n\t * @private\n\t */\n\t_handleFocusChange() {\n\t\tconst editor = this.editor;\n\n\t\t// Hide the panel View when editor loses focus but no the other way around.\n\t\tthis.listenTo( editor.ui.focusTracker, 'change:isFocused', ( evt, name, isFocused ) => {\n\t\t\tif ( this._balloon.visibleView === this.toolbarView && !isFocused ) {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/model/document~Document#selection} change and show or hide toolbar.\n\t *\n\t * Note that in this case it's better to listen to {@link module:engine/model/document~Document model document}\n\t * selection instead of {@link module:engine/view/document~Document view document} selection because the first one\n\t * doesn't fire `change` event after text style change (like bold or italic) and toolbar doesn't blink.\n\t *\n\t * @private\n\t */\n\t_handleSelectionChange() {\n\t\tconst selection = this.editor.document.selection;\n\t\tconst editingView = this.editor.editing.view;\n\n\t\tthis.listenTo( selection, 'change:range', ( evt, data ) => {\n\t\t\t// When the selection is not changed by a collaboration and when is not collapsed.\n\t\t\tif ( data.directChange || selection.isCollapsed ) {\n\t\t\t\t// Hide the toolbar when the selection starts changing.\n\t\t\t\tthis.hide();\n\t\t\t}\n\n\t\t\t// Fire internal `_selectionChangeDebounced` when the selection stops changing.\n\t\t\tthis._fireSelectionChangeDebounced();\n\t\t} );\n\n\t\t// Hide the toolbar when the selection stops changing.\n\t\tthis.listenTo( this, '_selectionChangeDebounced', () => {\n\t\t\t// This implementation assumes that only noncollapsed selections gets the contextual toolbar.\n\t\t\tif ( editingView.isFocused && !editingView.selection.isCollapsed ) {\n\t\t\t\tthis.show();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the toolbar and attaches it to the selection.\n\t *\n\t * Fires {@link #event:show} event which can be stopped to prevent the toolbar from showing up.\n\t */\n\tshow() {\n\t\t// Do not add the toolbar to the balloon stack twice.\n\t\tif ( this._balloon.hasView( this.toolbarView ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Don not show the toolbar when all components inside are disabled\n\t\t// see https://github.com/ckeditor/ckeditor5-ui/issues/269.\n\t\tif ( Array.from( this.toolbarView.items ).every( item => item.isEnabled !== undefined && !item.isEnabled ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Update the toolbar position upon #render (e.g. external document changes)\n\t\t// while it's visible.\n\t\tthis.listenTo( this.editor.editing.view, 'render', () => {\n\t\t\tthis._balloon.updatePosition( this._getBalloonPositionData() );\n\t\t} );\n\n\t\t// Add the toolbar to the common editor contextual balloon.\n\t\tthis._balloon.add( {\n\t\t\tview: this.toolbarView,\n\t\t\tposition: this._getBalloonPositionData(),\n\t\t\tballoonClassName: 'ck-toolbar-container ck-editor-toolbar-container'\n\t\t} );\n\t}\n\n\t/**\n\t * Hides the toolbar.\n\t */\n\thide() {\n\t\tif ( this._balloon.hasView( this.toolbarView ) ) {\n\t\t\tthis.stopListening( this.editor.editing.view, 'render' );\n\t\t\tthis._balloon.remove( this.toolbarView );\n\t\t}\n\t}\n\n\t/**\n\t * Returns positioning options for the {@link #_balloon}. They control the way balloon is attached\n\t * to the selection.\n\t *\n\t * @private\n\t * @returns {module:utils/dom/position~Options}\n\t */\n\t_getBalloonPositionData() {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\n\t\t// Get direction of the selection.\n\t\tconst isBackward = editingView.selection.isBackward;\n\n\t\treturn {\n\t\t\t// Because the target for BalloonPanelView is a Rect (not DOMRange), it's geometry will stay fixed\n\t\t\t// as the window scrolls. To let the BalloonPanelView follow such Rect, is must be continuously\n\t\t\t// computed and hence, the target is defined as a function instead of a static value.\n\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/195\n\t\t\ttarget: () => {\n\t\t\t\tconst range = editingView.selection.getFirstRange();\n\t\t\t\tconst rangeRects = Rect.getDomRangeRects( editingView.domConverter.viewRangeToDom( range ) );\n\n\t\t\t\t// Select the proper range rect depending on the direction of the selection.\n\t\t\t\tif ( isBackward ) {\n\t\t\t\t\treturn rangeRects[ 0 ];\n\t\t\t\t} else {\n\t\t\t\t\t// Ditch the zero-width \"orphan\" rect in the next line for the forward selection if there's\n\t\t\t\t\t// another one preceding it. It is not rendered as a selection by the web browser anyway.\n\t\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/308\n\t\t\t\t\tif ( rangeRects.length > 1 && rangeRects[ rangeRects.length - 1 ].width === 0 ) {\n\t\t\t\t\t\trangeRects.pop();\n\t\t\t\t\t}\n\n\t\t\t\t\treturn rangeRects[ rangeRects.length - 1 ];\n\t\t\t\t}\n\t\t\t},\n\t\t\tpositions: getBalloonPositions( isBackward )\n\t\t};\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis._fireSelectionChangeDebounced.cancel();\n\t\tthis.stopListening();\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * This event is fired just before the toolbar shows up. Stopping this event will prevent this.\n\t *\n\t * @event show\n\t */\n\n\t/**\n\t * This is internal plugin event which is fired 200 ms after model selection last change.\n\t * This is to makes easy test debounced action without need to use `setTimeout`.\n\t *\n\t * @protected\n\t * @event _selectionChangeDebounced\n\t */\n}\n\n// Returns toolbar positions for the given direction of the selection.\n//\n// @private\n// @param {Boolean} isBackward\n// @returns {Array.<module:utils/dom/position~Position>}\nfunction getBalloonPositions( isBackward ) {\n\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\n\treturn isBackward ? [\n\t\tdefaultPositions.northWestArrowSouth,\n\t\tdefaultPositions.northWestArrowSouthWest,\n\t\tdefaultPositions.northWestArrowSouthEast,\n\t\tdefaultPositions.southWestArrowNorth,\n\t\tdefaultPositions.southWestArrowNorthWest,\n\t\tdefaultPositions.southWestArrowNorthEast\n\t] : [\n\t\tdefaultPositions.southEastArrowNorth,\n\t\tdefaultPositions.southEastArrowNorthEast,\n\t\tdefaultPositions.southEastArrowNorthWest,\n\t\tdefaultPositions.northEastArrowSouth,\n\t\tdefaultPositions.northEastArrowSouthEast,\n\t\tdefaultPositions.northEastArrowSouthWest\n\t];\n}\n\n/**\n * Contextual toolbar configuration. Used by the {@link module:ui/toolbar/contextual/contextualtoolbar~ContextualToolbar}\n * feature.\n *\n *\t\tconst config = {\n *\t\t\tcontextualToolbar: [ 'bold', 'italic', 'undo', 'redo' ]\n *\t\t};\n *\n * You can also use `'|'` to create a separator between groups of items:\n *\n *\t\tconst config = {\n *\t\t\tcontextualToolbar: [ 'bold', 'italic', | 'undo', 'redo' ]\n *\t\t};\n *\n * Read also about configuring the main editor toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.\n *\n * @member {Array.<String>|Object} module:core/editor/editorconfig~EditorConfig#contextualToolbar\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/toolbar/contextual/contextualtoolbar.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/componentfactory\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * A helper class implementing the UI component ({@link module:ui/view~View view}) factory.\n *\n * It allows functions producing specific UI components to be registered under their unique names\n * in the factory. A registered component can be then instantiated by providing its name.\n * Note that names are case insensitive.\n *\n *\t\t// The editor provides localization tools for the factory.\n *\t\tconst factory = new ComponentFactory( editor );\n *\n *\t\tfactory.add( 'foo', locale => new FooView( locale ) );\n *\t\tfactory.add( 'bar', locale => new BarView( locale ) );\n *\n *\t\t// An instance of FooView.\n *\t\tconst fooInstance = factory.create( 'foo' );\n *\n *\t\t// Names are case insensitive so this is also allowed:\n *\t\tconst barInstance = factory.create( 'Bar' );\n *\n * The {@link module:core/editor/editor~Editor#locale editor locale} is passed to the factory\n * function when {@link module:ui/componentfactory~ComponentFactory#create} is called.\n */\nexport default class ComponentFactory {\n\t/**\n\t * Creates an instance of the factory.\n\t *\n\t * @constructor\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance that the factory belongs to.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * Registered component factories.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._components = new Map();\n\t}\n\n\t/**\n\t * Returns an iterator of registered component names. Names are returned in lower case.\n\t *\n\t * @returns {Iterator.<String>}\n\t */\n\t* names() {\n\t\tyield* this._components.keys();\n\t}\n\n\t/**\n\t * Registers a component factory function that will be used by the\n\t * {@link #create create} method and called with the\n\t * {@link module:core/editor/editor~Editor#locale editor locale} as an argument,\n\t * allowing localization of the {@link module:ui/view~View view}.\n\t *\n\t * @param {String} name The name of the component.\n\t * @param {Function} callback The callback that returns the component.\n\t */\n\tadd( name, callback ) {\n\t\tif ( this.has( name ) ) {\n\t\t\t/**\n\t\t\t * The item already exists in the component factory.\n\t\t\t *\n\t\t\t * @error componentfactory-item-exists\n\t\t\t * @param {String} name The name of the component.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'componentfactory-item-exists: The item already exists in the component factory.', { name }\n\t\t\t);\n\t\t}\n\n\t\tthis._components.set( getNormalized( name ), callback );\n\t}\n\n\t/**\n\t * Creates an instance of a component registered in the factory under a specific name.\n\t *\n\t * When called, the {@link module:core/editor/editor~Editor#locale editor locale} is passed to\n\t * the previously {@link #add added} factory function, allowing localization of the\n\t * {@link module:ui/view~View view}.\n\t *\n\t * @param {String} name The name of the component.\n\t * @returns {module:ui/view~View} The instantiated component view.\n\t */\n\tcreate( name ) {\n\t\tif ( !this.has( name ) ) {\n\t\t\t/**\n\t\t\t * The required component is not registered in the component factory. Please make sure\n\t\t\t * the provided name is correct and the component has been correctly\n\t\t\t * {@link #add added} to the factory.\n\t\t\t *\n\t\t\t * @error componentfactory-item-missing\n\t\t\t * @param {String} name The name of the missing component.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'componentfactory-item-missing: The required component is not registered in the factory.', { name }\n\t\t\t);\n\t\t}\n\n\t\treturn this._components.get( getNormalized( name ) )( this.editor.locale );\n\t}\n\n\t/**\n\t * Checks if a component of a given name is registered in the factory.\n\t *\n\t * @param {String} name The name of the component.\n\t * @returns {Boolean}\n\t */\n\thas( name ) {\n\t\treturn this._components.has( getNormalized( name ) );\n\t}\n}\n\n//\n// Ensures that the component name used as the key in the internal map is in lower case.\n//\n// @private\n// @param {String} name\n// @returns {String}\nfunction getNormalized( name ) {\n\treturn String( name ).toLowerCase();\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/componentfactory.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/enabletoolbarkeyboardfocus\n */\n\n/**\n * Enables focus/blur toolbar navigation using `Alt+F10` and `Esc` keystrokes.\n *\n * @param {Object} options Options of the utility.\n * @param {*} options.origin A view to which the focus will return when `Esc` is pressed and\n * `options.toolbar` is focused.\n * @param {module:utils/keystrokehandler~KeystrokeHandler} options.originKeystrokeHandler A keystroke\n * handler to register `Alt+F10` keystroke.\n * @param {module:utils/focustracker~FocusTracker} options.originFocusTracker A focus tracker\n * for `options.origin`.\n * @param {module:ui/toolbar/toolbarview~ToolbarView} options.toolbar A toolbar which is to gain\n * focus when `Alt+F10` is pressed.\n * @param {Function} [options.beforeFocus] A callback executed before the `options.toolbar` gains focus\n * upon the `Alt+F10` keystroke.\n * @param {Function} [options.afterBlur] A callback executed after `options.toolbar` loses focus upon\n * `Esc` keystroke but before the focus goes back to `options.origin`.\n */\nexport default function enableToolbarKeyboardFocus( {\n\torigin,\n\toriginKeystrokeHandler,\n\toriginFocusTracker,\n\ttoolbar,\n\tbeforeFocus,\n\tafterBlur\n} ) {\n\t// Because toolbar items can get focus, the overall state of the toolbar must\n\t// also be tracked.\n\toriginFocusTracker.add( toolbar.element );\n\n\t// Focus the toolbar on the keystroke, if not already focused.\n\toriginKeystrokeHandler.set( 'Alt+F10', ( data, cancel ) => {\n\t\tif ( originFocusTracker.isFocused && !toolbar.focusTracker.isFocused ) {\n\t\t\tif ( beforeFocus ) {\n\t\t\t\tbeforeFocus();\n\t\t\t}\n\n\t\t\ttoolbar.focus();\n\n\t\t\tcancel();\n\t\t}\n\t} );\n\n\t// Blur the toolbar and bring the focus back to origin.\n\ttoolbar.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\tif ( toolbar.focusTracker.isFocused ) {\n\t\t\torigin.focus();\n\n\t\t\tif ( afterBlur ) {\n\t\t\t\tafterBlur();\n\t\t\t}\n\n\t\t\tcancel();\n\t\t}\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/toolbar/enabletoolbarkeyboardfocus.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module editor-balloon/ballooneditorui\n */\n\nimport ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport enableToolbarKeyboardFocus from '@ckeditor/ckeditor5-ui/src/toolbar/enabletoolbarkeyboardfocus';\n\n/**\n * The balloon editor UI class.\n *\n * @implements module:core/editor/editorui~EditorUI\n */\nexport default class BalloonEditorUI {\n\t/**\n\t * Creates an instance of the balloon editor UI class.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {module:ui/editorui/editoruiview~EditorUIView} view The view of the UI.\n\t */\n\tconstructor( editor, view ) {\n\t\t/**\n\t\t * @inheritDoc\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t */\n\t\tthis.view = view;\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t */\n\t\tthis.componentFactory = new ComponentFactory( editor );\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\t}\n\n\t/**\n\t * Initializes the UI.\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst view = this.view;\n\t\tconst contextualToolbar = editor.plugins.get( 'ContextualToolbar' );\n\n\t\tview.render();\n\n\t\t// Setup the editable.\n\t\tconst editingRoot = editor.editing.createRoot( view.editableElement );\n\t\tview.editable.bind( 'isReadOnly' ).to( editingRoot );\n\n\t\t// Bind to focusTracker instead of editor.editing.view because otherwise\n\t\t// focused editable styles disappear when view#toolbar is focused.\n\t\tview.editable.bind( 'isFocused' ).to( this.focusTracker );\n\t\tview.editable.name = editingRoot.rootName;\n\n\t\tthis.focusTracker.add( view.editableElement );\n\n\t\tenableToolbarKeyboardFocus( {\n\t\t\torigin: editor.editing.view,\n\t\t\toriginFocusTracker: this.focusTracker,\n\t\t\toriginKeystrokeHandler: editor.keystrokes,\n\t\t\ttoolbar: contextualToolbar.toolbarView,\n\t\t\tbeforeFocus() {\n\t\t\t\tcontextualToolbar.show();\n\t\t\t},\n\t\t\tafterBlur() {\n\t\t\t\tcontextualToolbar.hide();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Destroys the UI.\n\t */\n\tdestroy() {\n\t\tthis.view.destroy();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-editor-balloon/src/ballooneditorui.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/datatransfer\n */\n\n/**\n * Facade over the native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.\n */\nexport default class DataTransfer {\n\tconstructor( nativeDataTransfer ) {\n\t\t/**\n\t\t * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<File>} #files\n\t\t */\n\t\tthis.files = getFiles( nativeDataTransfer );\n\n\t\t/**\n\t\t * The native DataTransfer object.\n\t\t *\n\t\t * @private\n\t\t * @member {DataTransfer} #_native\n\t\t */\n\t\tthis._native = nativeDataTransfer;\n\t}\n\n\t/**\n\t * Returns an array of available native content types.\n\t *\n\t * @returns {Array.<String>}\n\t */\n\tget types() {\n\t\treturn this._native.types;\n\t}\n\n\t/**\n\t * Gets data from the data transfer by its mime type.\n\t *\n\t *\t\tdataTransfer.getData( 'text/plain' );\n\t *\n\t * @param {String} type The mime type. E.g. `text/html` or `text/plain`.\n\t * @returns {String}\n\t */\n\tgetData( type ) {\n\t\treturn this._native.getData( type );\n\t}\n\n\t/**\n\t * Sets data in the data transfer.\n\t *\n\t * @param {String} type The mime type. E.g. `text/html` or `text/plain`.\n\t * @param {String} data\n\t */\n\tsetData( type, data ) {\n\t\tthis._native.setData( type, data );\n\t}\n}\n\nfunction getFiles( nativeDataTransfer ) {\n\t// DataTransfer.files and items are Array-like and might not have an iterable interface.\n\tconst files = nativeDataTransfer.files ? Array.from( nativeDataTransfer.files ) : [];\n\tconst items = nativeDataTransfer.items ? Array.from( nativeDataTransfer.items ) : [];\n\n\tif ( files.length ) {\n\t\treturn files;\n\t}\n\t// Chrome have empty DataTransfer.files, but let get files through the items interface.\n\treturn items\n\t\t.filter( item => item.kind === 'file' )\n\t\t.map( item => item.getAsFile() );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-clipboard/src/datatransfer.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/clipboardobserver\n */\n\nimport DomEventObserver from '@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver';\nimport DataTransfer from './datatransfer';\n\n/**\n * {@link module:engine/view/document~Document#event:paste Paste} 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/document~Document} by the {@link module:engine/view/document~Document#addObserver} method.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class ClipboardObserver extends DomEventObserver {\n\tconstructor( doc ) {\n\t\tsuper( doc );\n\n\t\tthis.domEventType = [ 'paste', 'copy', 'cut', 'drop', 'dragover' ];\n\n\t\tthis.listenTo( doc, 'paste', handleInput, { priority: 'low' } );\n\t\tthis.listenTo( doc, 'drop', handleInput, { priority: 'low' } );\n\n\t\tfunction handleInput( evt, data ) {\n\t\t\tdata.preventDefault();\n\n\t\t\tconst targetRanges = data.dropRange ? [ data.dropRange ] : Array.from( doc.selection.getRanges() );\n\n\t\t\tdoc.fire( 'clipboardInput', {\n\t\t\t\tdataTransfer: data.dataTransfer,\n\t\t\t\ttargetRanges\n\t\t\t} );\n\t\t}\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tconst evtData = {\n\t\t\tdataTransfer: new DataTransfer( domEvent.clipboardData ? domEvent.clipboardData : domEvent.dataTransfer )\n\t\t};\n\n\t\tif ( domEvent.type == 'drop' ) {\n\t\t\tevtData.dropRange = getDropViewRange( this.document, domEvent );\n\t\t}\n\n\t\tthis.fire( domEvent.type, domEvent, evtData );\n\t}\n}\n\nfunction getDropViewRange( doc, domEvent ) {\n\tconst domDoc = domEvent.target.ownerDocument;\n\tconst x = domEvent.clientX;\n\tconst y = domEvent.clientY;\n\tlet domRange;\n\n\t// Webkit & Blink.\n\tif ( domDoc.caretRangeFromPoint && domDoc.caretRangeFromPoint( x, y ) ) {\n\t\tdomRange = domDoc.caretRangeFromPoint( x, y );\n\t}\n\t// FF.\n\telse if ( domEvent.rangeParent ) {\n\t\tdomRange = domDoc.createRange();\n\t\tdomRange.setStart( domEvent.rangeParent, domEvent.rangeOffset );\n\t\tdomRange.collapse( true );\n\t}\n\n\tif ( domRange ) {\n\t\treturn doc.domConverter.domRangeToView( domRange );\n\t} else {\n\t\treturn doc.selection.getFirstRange();\n\t}\n}\n\n/**\n * Fired as a continuation of {@link #event:paste} and {@link #event:drop} events.\n * It's part of the {@link module:clipboard/clipboard~Clipboard \"clipboard pipeline\"}.\n *\n * Fired with a `dataTransfer` which comes from the clipboard and which content should be processed\n * and inserted into the editor.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/document~Document#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboard~Clipboard\n * @event module:engine/view/document~Document#event:clipboardInput\n * @param {Object} data Event data.\n * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer Data transfer instance.\n * @param {Array.<module:engine/view/range~Range>} data.targetRanges Ranges which are the target of the operation\n * (usually into which the content should be inserted).\n * If clipboard input was triggered by a paste operation, then these are the selection ranges. If by a drop operation,\n * then it's the drop position (which can be different than the selection at the moment of drop).\n */\n\n/**\n * Fired when user drags content over one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/document~Document#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n * @event module:engine/view/document~Document#event:dragover\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n */\n\n/**\n * Fired when user dropped content into one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/document~Document#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n * @event module:engine/view/document~Document#event:drop\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n * @param {module:engine/view/range~Range} dropRange The position into which the content is dropped.\n */\n\n/**\n * Fired when user pasted content into one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/document~Document#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n * @event module:engine/view/document~Document#event:paste\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n */\n\n/**\n * Fired when user copied content from one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/document~Document#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @event module:engine/view/document~Document#event:copy\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n */\n\n/**\n * Fired when user cut content from one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/document~Document#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @event module:engine/view/document~Document#event:cut\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n */\n\n/**\n * The value of the {@link module:engine/view/document~Document#event:paste},\n * {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut} events.\n *\n * In order to access clipboard data use `dataTransfer` property.\n *\n * @class module:clipboard/clipboardobserver~ClipboardEventData\n * @extends module:engine/view/observer/domeventdata~DomEventData\n */\n\n/**\n * Data transfer instance.\n *\n * @readonly\n * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboardobserver~ClipboardEventData#dataTransfer\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-clipboard/src/clipboardobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/utils/plaintexttohtml\n */\n\n/**\n * Converts plain text to its HTML-ized version.\n *\n * @param {String} text The plain text to convert.\n * @returns {String} HTML generated from the plain text.\n */\nexport default function plainTextToHtml( text ) {\n\ttext = text\n\t\t// Encode <>.\n\t\t.replace( /</g, '&lt;' )\n\t\t.replace( />/g, '&gt;' )\n\t\t// Creates paragraphs for double line breaks and change single line breaks to spaces.\n\t\t// In the future single line breaks may be converted into <br>s.\n\t\t.replace( /\\n\\n/g, '</p><p>' )\n\t\t.replace( /\\n/g, ' ' )\n\t\t// Preserve trailing spaces (only the first and last one the rest is handled below).\n\t\t.replace( /^\\s/, '&nbsp;' )\n\t\t.replace( /\\s$/, '&nbsp;' )\n\t\t// Preserve other subsequent spaces now.\n\t\t.replace( /\\s\\s/g, ' &nbsp;' );\n\n\tif ( text.indexOf( '</p><p>' ) > -1 ) {\n\t\t// If we created paragraphs above, add the trailing ones.\n\t\ttext = `<p>${ text }</p>`;\n\t}\n\n\t// TODO:\n\t// * What about '\\nfoo' vs ' foo'?\n\n\treturn text;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-clipboard/src/utils/plaintexttohtml.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/utils/normalizeclipboarddata\n */\n\n/**\n * Removes some popular browser quirks out of the clipboard data (HTML).\n *\n * @param {String} data The HTML data to normalize.\n * @returns {String} Normalized HTML.\n */\nexport default function normalizeClipboardData( data ) {\n\treturn data\n\t\t.replace( /<span(?: class=\"Apple-converted-space\"|)>(\\s+)<\\/span>/g, ( fullMatch, spaces ) => {\n\t\t\t// Handle the most popular and problematic case when even a single space becomes an nbsp;.\n\t\t\t// Decode those to normal spaces. Read more in https://github.com/ckeditor/ckeditor5-clipboard/issues/2.\n\t\t\tif ( spaces.length == 1 ) {\n\t\t\t\treturn ' ';\n\t\t\t}\n\n\t\t\treturn spaces;\n\t\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-clipboard/src/utils/normalizeclipboarddata.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/utils/viewtoplaintext\n */\n\n// Elements which should not have empty-line padding.\n// Most `view.ContainerElement` want to be separate by new-line, but some are creating one structure\n// together (like `<li>`) so it is better to separate them by only one \"\\n\".\nconst smallPaddingElements = [ 'figcaption', 'li' ];\n\n/**\n * Converts {@link module:engine/view/item~Item view item} and all of its children to plain text.\n *\n * @param {module:engine/view/item~Item} viewItem View item to convert.\n * @returns {String} Plain text representation of `viewItem`.\n */\nexport default function viewToPlainText( viewItem ) {\n\tlet text = '';\n\n\tif ( viewItem.is( 'text' ) || viewItem.is( 'textProxy' ) ) {\n\t\t// If item is `Text` or `TextProxy` simple take its text data.\n\t\ttext = viewItem.data;\n\t} else if ( viewItem.is( 'img' ) && viewItem.hasAttribute( 'alt' ) ) {\n\t\t// Special case for images - use alt attribute if it is provided.\n\t\ttext = viewItem.getAttribute( 'alt' );\n\t} else {\n\t\t// Other elements are document fragments, attribute elements or container elements.\n\t\t// They don't have their own text value, so convert their children.\n\t\tlet prev = null;\n\n\t\tfor ( const child of viewItem.getChildren() ) {\n\t\t\tconst childText = viewToPlainText( child );\n\n\t\t\t// Separate container element children with one or more new-line characters.\n\t\t\tif ( prev && ( prev.is( 'containerElement' ) || child.is( 'containerElement' ) ) ) {\n\t\t\t\tif ( smallPaddingElements.includes( prev.name ) || smallPaddingElements.includes( child.name ) ) {\n\t\t\t\t\ttext += '\\n';\n\t\t\t\t} else {\n\t\t\t\t\ttext += '\\n\\n';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext += childText;\n\t\t\tprev = child;\n\t\t}\n\t}\n\n\treturn text;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-clipboard/src/utils/viewtoplaintext.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/clipboard\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport ClipboardObserver from './clipboardobserver';\n\nimport plainTextToHtml from './utils/plaintexttohtml';\nimport normalizeClipboardHtml from './utils/normalizeclipboarddata';\nimport viewToPlainText from './utils/viewtoplaintext.js';\n\nimport HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';\n\n/**\n * The clipboard feature. Currently, it's responsible for intercepting the `paste` and `drop` events and\n * passing the pasted content through the clipboard pipeline.\n *\n * # Clipboard input pipeline\n *\n * The feature creates the clipboard input pipeline which allows processing clipboard content\n * before it gets inserted into the editor. The pipeline consists of two events on which\n * the features can listen in order to modify or totally override the default behavior.\n *\n * ## On {@link module:engine/view/document~Document#event:paste} and {@link module:engine/view/document~Document#event:drop}\n *\n * The default action is to:\n *\n * 1. get HTML or plain text from the clipboard,\n * 2. prevent the default action of the native `paste` or `drop` event,\n * 3. fire {@link module:engine/view/document~Document#event:clipboardInput} with a\n * {@link module:clipboard/datatransfer~DataTransfer `dataTransfer`} property.\n * 4. fire {@link module:clipboard/clipboard~Clipboard#event:inputTransformation} with a `data` containing the clipboard data parsed to\n * a {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.\n *\n * These action are performed by a low priority listeners, so they can be overridden by a normal ones\n * when a deeper change in pasting behavior is needed. For example, a feature which wants to differently read\n * data from the clipboard (the {@link module:clipboard/datatransfer~DataTransfer `DataTransfer`}).\n * should plug a listener at this stage.\n *\n * ## On {@link module:engine/view/document~Document#event:clipboardInput}\n *\n * This action is performed by a low priority listener, so it can be overridden by a normal one.\n *\n * At this stage the dataTransfer object can be processed by the features, which want to transform the original dataTransform.\n *\n *\t\tthis.listenTo( editor.editing.view, 'clipboardInput', ( evt, data ) => {\n *\t\t\tconst content = customTransform( data.dataTransfer.get( 'text/html' ) );\n *\t\t\tconst transformedContent = transform( content );\n *\t\t\tdata.dataTransfer.set( 'text/html', transformedContent );\n *\t\t} );\n *\n * ## On {@link module:clipboard/clipboard~Clipboard#event:inputTransformation}\n *\n * The default action is to insert the content (`data.content`, represented by a\n * {@link module:engine/view/documentfragment~DocumentFragment}) to an editor if the data is not empty.\n *\n * This action is performed by a low priority listener, so it can be overridden by a normal one.\n *\n * At this stage the pasted content can be processed by the features. E.g. a feature which wants to transform\n * a pasted text into a link can be implemented in this way:\n *\n *\t\tthis.listenTo( editor.plugins.get( 'Clipboard' ), 'inputTransformation', ( evt, data ) => {\n *\t\t\tif ( data.content.childCount == 1 && isUrlText( data.content.getChild( 0 ) ) ) {\n *\t\t\t\tconst linkUrl = data.content.getChild( 0 ).data;\n *\n *\t\t\t\tdata.content = new ViewDocumentFragment( [\n *\t\t\t\t\tViewElement(\n *\t\t\t\t\t\t'a',\n *\t\t\t\t\t\t{ href: linkUrl },\n *\t\t\t\t\t\t[ new ViewText( linkUrl ) ]\n *\t\t\t\t\t)\n *\t\t\t\t] );\n *\t\t\t}\n *\t\t} );\n *\n * # Clipboard output pipeline\n *\n * The output pipeline is the equivalent of the input pipeline but for the copy and cut operations.\n * It allows to process the content which will be then put into the clipboard or to override the whole process.\n *\n * ## On {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut}\n *\n * The default action is to:\n *\n * 1. {@link module:engine/controller/datacontroller~DataController#getSelectedContent get selected content} from the editor,\n * 2. prevent the default action of the native `copy` or `cut` event,\n * 3. fire {@link module:engine/view/document~Document#event:clipboardOutput} with a clone of the selected content\n * converted to a {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.\n *\n * ## On {@link module:engine/view/document~Document#event:clipboardOutput}\n *\n * The default action is to put the content (`data.content`, represented by a\n * {@link module:engine/view/documentfragment~DocumentFragment}) to the clipboard as HTML. In case of the cut operation,\n * the selected content is also deleted from the editor.\n *\n * This action is performed by a low priority listener, so it can be overridden by a normal one.\n *\n * At this stage the copied/cut content can be processed by the features.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Clipboard extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Clipboard';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst doc = editor.document;\n\t\tconst editingView = editor.editing.view;\n\n\t\t/**\n\t\t * Data processor used to convert pasted HTML to a view structure.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/dataprocessor/htmldataprocessor~HtmlDataProcessor} #_htmlDataProcessor\n\t\t */\n\t\tthis._htmlDataProcessor = new HtmlDataProcessor();\n\n\t\teditingView.addObserver( ClipboardObserver );\n\n\t\t// The clipboard paste pipeline.\n\n\t\tthis.listenTo( editingView, 'clipboardInput', ( evt, data ) => {\n\t\t\t// Pasting and dropping is disabled when editor is read-only.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26.\n\t\t\tif ( editor.isReadOnly ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst dataTransfer = data.dataTransfer;\n\t\t\tlet content = '';\n\n\t\t\tif ( dataTransfer.getData( 'text/html' ) ) {\n\t\t\t\tcontent = normalizeClipboardHtml( dataTransfer.getData( 'text/html' ) );\n\t\t\t} else if ( dataTransfer.getData( 'text/plain' ) ) {\n\t\t\t\tcontent = plainTextToHtml( dataTransfer.getData( 'text/plain' ) );\n\t\t\t}\n\n\t\t\tcontent = this._htmlDataProcessor.toView( content );\n\n\t\t\tthis.fire( 'inputTransformation', { content } );\n\n\t\t\teditingView.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo( this, 'inputTransformation', ( evt, data ) => {\n\t\t\tif ( !data.content.isEmpty ) {\n\t\t\t\tconst dataController = this.editor.data;\n\n\t\t\t\t// Convert the pasted content to a model document fragment.\n\t\t\t\t// Conversion is contextual, but in this case we need an \"all allowed\" context and for that\n\t\t\t\t// we use the $clipboardHolder item.\n\t\t\t\tconst modelFragment = dataController.toModel( data.content, '$clipboardHolder' );\n\n\t\t\t\tif ( modelFragment.childCount == 0 ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tdoc.enqueueChanges( () => {\n\t\t\t\t\tdataController.insertContent( modelFragment, doc.selection );\n\t\t\t\t} );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// The clipboard copy/cut pipeline.\n\n\t\tfunction onCopyCut( evt, data ) {\n\t\t\tconst dataTransfer = data.dataTransfer;\n\t\t\tconst content = editor.data.toView( editor.data.getSelectedContent( doc.selection ) );\n\n\t\t\tdata.preventDefault();\n\n\t\t\teditingView.fire( 'clipboardOutput', { dataTransfer, content, method: evt.name } );\n\t\t}\n\n\t\tthis.listenTo( editingView, 'copy', onCopyCut, { priority: 'low' } );\n\t\tthis.listenTo( editingView, 'cut', ( evt, data ) => {\n\t\t\t// Cutting is disabled when editor is read-only.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26.\n\t\t\tif ( editor.isReadOnly ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t} else {\n\t\t\t\tonCopyCut( evt, data );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo( editingView, 'clipboardOutput', ( evt, data ) => {\n\t\t\tif ( !data.content.isEmpty ) {\n\t\t\t\tdata.dataTransfer.setData( 'text/html', this._htmlDataProcessor.toData( data.content ) );\n\t\t\t\tdata.dataTransfer.setData( 'text/plain', viewToPlainText( data.content ) );\n\t\t\t}\n\n\t\t\tif ( data.method == 'cut' ) {\n\t\t\t\tdoc.enqueueChanges( () => {\n\t\t\t\t\teditor.data.deleteContent( doc.selection, doc.batch() );\n\t\t\t\t} );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t}\n}\n\n/**\n * Fired with a `content`, which comes from the clipboard (was pasted or dropped) and\n * should be processed in order to be inserted into the editor.\n * It's part of the {@link module:clipboard/clipboard~Clipboard \"clipboard pipeline\"}.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboard~Clipboard\n * @event module:clipboard/clipboard~Clipboard#event:inputTransformation\n * @param {Object} data Event data.\n * @param {module:engine/view/documentfragment~DocumentFragment} data.content Event data. Content to be inserted into the editor.\n * It can be modified by the event listeners. Read more about the clipboard pipelines in {@link module:clipboard/clipboard~Clipboard}\n */\n\n/**\n * Fired on {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut}\n * with a copy of selected content. The content can be processed before it ends up in the clipboard.\n * It's part of the {@link module:clipboard/clipboard~Clipboard \"clipboard pipeline\"}.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboard~Clipboard\n * @event module:engine/view/document~Document#event:clipboardOutput\n * @param {module:clipboard/clipboard~ClipboardOutputEventData} data Event data.\n */\n\n/**\n * The value of the {@link module:engine/view/document~Document#event:clipboardOutput} event.\n *\n * @class module:clipboard/clipboard~ClipboardOutputEventData\n */\n\n/**\n * Data transfer instance.\n *\n * @readonly\n * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboard~ClipboardOutputEventData#dataTransfer\n */\n\n/**\n * Content to be put into the clipboard. It can be modified by the event listeners.\n * Read more about the clipboard pipelines in {@link module:clipboard/clipboard~Clipboard}.\n *\n * @member {module:engine/view/documentfragment~DocumentFragment} module:clipboard/clipboard~ClipboardOutputEventData#content\n */\n\n/**\n * Whether the event was triggered by copy or cut operation.\n *\n * @member {'copy'|'cut'} module:clipboard/clipboard~ClipboardOutputEventData#method\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-clipboard/src/clipboard.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module enter/entercommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport Position from '@ckeditor/ckeditor5-engine/src/model/position';\n\n/**\n * Enter command. It is used by the {@link module:enter/enter~Enter Enter feature} to handle the <kbd>Enter</kbd> key.\n *\n * @extends module:core/command~Command\n */\nexport default class EnterCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst doc = this.editor.document;\n\t\tconst batch = doc.batch();\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tenterBlock( this.editor.data, batch, doc.selection, doc.schema );\n\n\t\t\tthis.fire( 'afterExecute', { batch } );\n\t\t} );\n\t}\n}\n\n// Creates a new block in the way that the <kbd>Enter</kbd> key is expected to work.\n//\n// @param {engine.controller.DataController} dataController\n// @param {module:engine/model/batch~Batch} batch A batch to which the deltas will be added.\n// @param {module:engine/model/selection~Selection} selection Selection on which the action should be performed.\n// @param {module:engine/model/schema~Schema} schema\nfunction enterBlock( dataController, batch, selection, schema ) {\n\tconst isSelectionEmpty = selection.isCollapsed;\n\tconst range = selection.getFirstRange();\n\tconst startElement = range.start.parent;\n\tconst endElement = range.end.parent;\n\n\t// Don't touch the roots and other limit elements.\n\tif ( schema.limits.has( startElement.name ) || schema.limits.has( endElement.name ) ) {\n\t\t// Delete the selected content but only if inside a single limit element.\n\t\t// Abort, when crossing limit elements boundary (e.g. <limit1>x[x</limit1>donttouchme<limit2>y]y</limit2>).\n\t\t// This is an edge case and it's hard to tell what should actually happen because such a selection\n\t\t// is not entirely valid.\n\t\tif ( !isSelectionEmpty && startElement == endElement ) {\n\t\t\tdataController.deleteContent( selection, batch );\n\t\t}\n\n\t\treturn;\n\t}\n\n\tif ( isSelectionEmpty ) {\n\t\tsplitBlock( batch, selection, range.start );\n\t} else {\n\t\tconst leaveUnmerged = !( range.start.isAtStart && range.end.isAtEnd );\n\t\tconst isContainedWithinOneElement = ( startElement == endElement );\n\n\t\tdataController.deleteContent( selection, batch, { leaveUnmerged } );\n\n\t\tif ( leaveUnmerged ) {\n\t\t\t// Partially selected elements.\n\t\t\t//\n\t\t\t// <h>x[xx]x</h>\t\t-> <h>x^x</h>\t\t\t-> <h>x</h><h>^x</h>\n\t\t\tif ( isContainedWithinOneElement ) {\n\t\t\t\tsplitBlock( batch, selection, selection.focus );\n\t\t\t}\n\t\t\t// Selection over multiple elements.\n\t\t\t//\n\t\t\t// <h>x[x</h><p>y]y<p>\t-> <h>x^</h><p>y</p>\t-> <h>x</h><p>^y</p>\n\t\t\telse {\n\t\t\t\tselection.setCollapsedAt( endElement );\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction splitBlock( batch, selection, splitPos ) {\n\tconst oldElement = splitPos.parent;\n\tconst newElement = new oldElement.constructor( oldElement.name, oldElement.getAttributes() );\n\n\tif ( splitPos.isAtEnd ) {\n\t\t// If the split is at the end of element, instead of splitting, just create a clone of position's parent\n\t\t// element and insert it after split element. The result is the same but less operations are done\n\t\t// and it's more semantically correct (when it comes to operational transformation).\n\t\tbatch.insert( Position.createAfter( splitPos.parent ), newElement );\n\t} else if ( splitPos.isAtStart ) {\n\t\t// If the split is at the start of element, instead of splitting, just create a clone of position's parent\n\t\t// element and insert it before split element. The result is the same but less operations are done\n\t\t// and it's more semantically correct (when it comes to operational transformation).\n\t\tbatch.insert( Position.createBefore( splitPos.parent ), newElement );\n\t} else {\n\t\tbatch.split( splitPos );\n\t}\n\n\tselection.setCollapsedAt( splitPos.parent.nextSibling );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-enter/src/entercommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module enter/enterobserver\n */\n\nimport Observer from '@ckeditor/ckeditor5-engine/src/view/observer/observer';\nimport DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * Enter observer introduces the {@link module:engine/view/document~Document#event:enter} event.\n *\n * @extends module:engine/view/observer~Observer\n */\nexport default class EnterObserver extends Observer {\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\tdocument.on( 'keydown', ( evt, data ) => {\n\t\t\tif ( this.isEnabled && data.keyCode == keyCodes.enter ) {\n\t\t\t\tdocument.fire( 'enter', new DomEventData( document, data.domEvent ) );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve() {}\n}\n\n/**\n * Event fired when the user presses the <kbd>Enter</kbd> key.\n *\n * Note: This event is fired by the {@link module:enter/enterobserver~EnterObserver observer}\n * (usually registered by the {@link module:enter/enter~Enter Enter feature}).\n *\n * @event module:engine/view/document~Document#event:enter\n * @param {module:engine/view/observer/domeventdata~DomEventData} data\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-enter/src/enterobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/difftochanges\n */\n\n/**\n * Creates a set of changes which need to be applied to the input in order to transform\n * it into the output. This function can be used with strings or arrays.\n *\n *\t\tconst input = Array.from( 'abc' );\n *\t\tconst output = Array.from( 'xaby' );\n *\t\tconst changes = diffToChanges( diff( input, output ), output );\n *\n *\t\tchanges.forEach( change => {\n *\t\t\tif ( change.type == 'insert' ) {\n *\t\t\t\tinput.splice( change.index, 0, ...change.values );\n *\t\t\t} else if ( change.type == 'delete' ) {\n *\t\t\t\tinput.splice( change.index, change.howMany );\n *\t\t\t}\n *\t\t} );\n *\n *\t\tinput.join( '' ) == output.join( '' ); // -> true\n *\n * @param {Array.<'equal'|'insert'|'delete'>} diff Result of {@link module:utils/diff~diff}.\n * @param {String|Array} output The string or array which was passed as diff's output.\n * @returns {Array.<Object>} Set of changes (insert or delete) which need to be applied to the input\n * in order to transform it into the output.\n */\nexport default function diffToChanges( diff, output ) {\n\tconst changes = [];\n\tlet index = 0;\n\tlet lastOperation;\n\n\tdiff.forEach( change => {\n\t\tif ( change == 'equal' ) {\n\t\t\tpushLast();\n\n\t\t\tindex++;\n\t\t} else if ( change == 'insert' ) {\n\t\t\tif ( isContinuationOf( 'insert' ) ) {\n\t\t\t\tlastOperation.values.push( output[ index ] );\n\t\t\t} else {\n\t\t\t\tpushLast();\n\n\t\t\t\tlastOperation = {\n\t\t\t\t\ttype: 'insert',\n\t\t\t\t\tindex,\n\t\t\t\t\tvalues: [ output[ index ] ]\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tindex++;\n\t\t} else /* if ( change == 'delete' ) */ {\n\t\t\tif ( isContinuationOf( 'delete' ) ) {\n\t\t\t\tlastOperation.howMany++;\n\t\t\t} else {\n\t\t\t\tpushLast();\n\n\t\t\t\tlastOperation = {\n\t\t\t\t\ttype: 'delete',\n\t\t\t\t\tindex,\n\t\t\t\t\thowMany: 1\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t} );\n\n\tpushLast();\n\n\treturn changes;\n\n\tfunction pushLast() {\n\t\tif ( lastOperation ) {\n\t\t\tchanges.push( lastOperation );\n\t\t\tlastOperation = null;\n\t\t}\n\t}\n\n\tfunction isContinuationOf( expected ) {\n\t\treturn lastOperation && lastOperation.type == expected;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/difftochanges.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/changebuffer\n */\n\nimport count from '@ckeditor/ckeditor5-utils/src/count';\n\n/**\n * Change buffer allows to group atomic changes (like characters that have been typed) into\n * {@link module:engine/model/batch~Batch batches}.\n *\n * Batches represent single undo steps, hence changes added to one single batch are undone together.\n *\n * The buffer has a configurable limit of atomic changes that it can accommodate. After the limit was\n * exceeded (see {@link ~ChangeBuffer#input}), a new batch is created in {@link ~ChangeBuffer#batch}.\n *\n * To use the change buffer you need to let it know about the number of changes that were added to the batch:\n *\n *\t\tconst buffer = new ChangeBuffer( document, LIMIT );\n *\n *\t\t// Later on in your feature:\n *\t\tbuffer.batch.insert( pos, insertedCharacters );\n *\t\tbuffer.input( insertedCharacters.length );\n *\n */\nexport default class ChangeBuffer {\n\t/**\n\t * Creates a new instance of the change buffer.\n\t *\n\t * @param {module:engine/model/document~Document} document\n\t * @param {Number} [limit=20] The maximum number of atomic changes which can be contained in one batch.\n\t */\n\tconstructor( doc, limit = 20 ) {\n\t\t/**\n\t\t * The document instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/document~Document} #document\n\t\t */\n\t\tthis.document = doc;\n\n\t\t/**\n\t\t * The number of atomic changes in the buffer. Once it exceeds the {@link #limit},\n\t\t * the {@link #batch batch} is set to a new one.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #size\n\t\t */\n\t\tthis.size = 0;\n\n\t\t/**\n\t\t * The maximum number of atomic changes which can be contained in one batch.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #limit\n\t\t */\n\t\tthis.limit = limit;\n\n\t\t/**\n\t\t * Whether the buffer is locked. A locked buffer cannot be reset unless it gets unlocked.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isLocked\n\t\t */\n\t\tthis.isLocked = false;\n\n\t\tthis._changeCallback = ( evt, type, changes, batch ) => {\n\t\t\tthis._onBatch( batch );\n\t\t};\n\n\t\tthis._selectionChangeCallback = () => {\n\t\t\tthis._reset();\n\t\t};\n\n\t\tdoc.on( 'change', this._changeCallback );\n\n\t\tdoc.selection.on( 'change:range', this._selectionChangeCallback );\n\n\t\tdoc.selection.on( 'change:attribute', this._selectionChangeCallback );\n\n\t\t/**\n\t\t * The current batch instance.\n\t\t *\n\t\t * @private\n\t\t * @member #_batch\n\t\t */\n\n\t\t/**\n\t\t * The callback to document the change event which later needs to be removed.\n\t\t *\n\t\t * @private\n\t\t * @member #_changeCallback\n\t\t */\n\n\t\t/**\n\t\t * The callback to document selection `change:attribute` and `change:range` events which resets the buffer.\n\t\t *\n\t\t * @private\n\t\t * @member #_selectionChangeCallback\n\t\t */\n\t}\n\n\t/**\n\t * The current batch to which a feature should add its deltas. Once the {@link #size}\n\t * is reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.\n\t *\n\t * @type {module:engine/model/batch~Batch}\n\t */\n\tget batch() {\n\t\tif ( !this._batch ) {\n\t\t\tthis._batch = this.document.batch();\n\t\t}\n\n\t\treturn this._batch;\n\t}\n\n\t/**\n\t * The input number of changes into the buffer. Once the {@link #size} is\n\t * reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.\n\t *\n\t * @param {Number} changeCount The number of atomic changes to input.\n\t */\n\tinput( changeCount ) {\n\t\tthis.size += changeCount;\n\n\t\tif ( this.size >= this.limit ) {\n\t\t\tthis._reset( true );\n\t\t}\n\t}\n\n\t/**\n\t * Locks the buffer.\n\t */\n\tlock() {\n\t\tthis.isLocked = true;\n\t}\n\n\t/**\n\t * Unlocks the buffer.\n\t */\n\tunlock() {\n\t\tthis.isLocked = false;\n\t}\n\n\t/**\n\t * Destroys the buffer.\n\t */\n\tdestroy() {\n\t\tthis.document.off( 'change', this._changeCallback );\n\t\tthis.document.selection.off( 'change:range', this._selectionChangeCallback );\n\t\tthis.document.selection.off( 'change:attribute', this._selectionChangeCallback );\n\t}\n\n\t/**\n\t * The method to be called in order to notify the buffer about batches which appeared in the document.\n\t * The method will check whether it is a new batch and in that case the buffer will be flushed.\n\t *\n\t * The reason why the buffer needs to be flushed whenever a new batch appears is that the changes added afterwards\n\t * should be added to a new batch. For instance, when the user types, then inserts an image, and then types again,\n\t * the characters typed after inserting the image should be added to a different batch than the characters typed before.\n\t *\n\t * @private\n\t * @param {module:engine/model/batch~Batch} batch The batch which appears in the document.\n\t */\n\t_onBatch( batch ) {\n\t\t// One operation means a newly created batch.\n\t\tif ( batch.type != 'transparent' && batch !== this._batch && count( batch.getOperations() ) <= 1 ) {\n\t\t\tthis._reset( true );\n\t\t}\n\t}\n\n\t/**\n\t * Resets the change buffer.\n\t *\n\t * @private\n\t * @param {Boolean} [ignoreLock] Whether internal lock {@link #isLocked} should be ignored.\n\t */\n\t_reset( ignoreLock ) {\n\t\tif ( !this.isLocked || ignoreLock ) {\n\t\t\tthis._batch = null;\n\t\t\tthis.size = 0;\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-typing/src/changebuffer.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/input\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';\nimport ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\nimport ViewText from '@ckeditor/ckeditor5-engine/src/view/text';\nimport diff from '@ckeditor/ckeditor5-utils/src/diff';\nimport diffToChanges from '@ckeditor/ckeditor5-utils/src/difftochanges';\nimport { getCode } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport DomConverter from '@ckeditor/ckeditor5-engine/src/view/domconverter';\nimport InputCommand from './inputcommand';\n\n/**\n * Handles text input coming from the keyboard or other input methods.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Input extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Input';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst inputCommand = new InputCommand( editor, editor.config.get( 'typing.undoStep' ) || 20 );\n\n\t\t// TODO The above default configuration value should be defined using editor.config.define() once it's fixed.\n\n\t\teditor.commands.add( 'input', inputCommand );\n\n\t\tthis.listenTo( editingView, 'keydown', ( evt, data ) => {\n\t\t\tthis._handleKeydown( data, inputCommand );\n\t\t}, { priority: 'lowest' } );\n\n\t\tthis.listenTo( editingView, 'mutations', ( evt, mutations, viewSelection ) => {\n\t\t\tthis._handleMutations( mutations, viewSelection );\n\t\t} );\n\t}\n\n\t/**\n\t * Handles the keydown event. We need to guess whether such keystroke is going to result\n\t * in typing. If so, then before character insertion happens, any selected content needs\n\t * to be deleted. Otherwise the default browser deletion mechanism would be\n\t * triggered, resulting in:\n\t *\n\t * * Hundreds of mutations which could not be handled.\n\t * * But most importantly, loss of control over how the content is being deleted.\n\t *\n\t * The method is used in a low-priority listener, hence allowing other listeners (e.g. delete or enter features)\n\t * to handle the event.\n\t *\n\t * @private\n\t * @param {module:engine/view/observer/keyobserver~KeyEventData} evtData\n\t * @param {module:typing/inputcommand~InputCommand} inputCommand\n\t */\n\t_handleKeydown( evtData, inputCommand ) {\n\t\tconst doc = this.editor.document;\n\t\tconst buffer = inputCommand.buffer;\n\n\t\t// By relying on the state of the input command we allow disabling the entire input easily\n\t\t// by just disabling the input command. We couldve used here the delete command but that\n\t\t// would mean requiring the delete feature which would block loading one without the other.\n\t\t// We could also check the editor.isReadOnly property, but that wouldn't allow to block\n\t\t// the input without blocking other features.\n\t\tif ( !inputCommand.isEnabled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isSafeKeystroke( evtData ) || doc.selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tbuffer.lock();\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tthis.editor.data.deleteContent( doc.selection, buffer.batch );\n\t\t} );\n\n\t\tbuffer.unlock();\n\t}\n\n\t/**\n\t * Handles DOM mutations.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n\t * module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n\t * @param {module:engine/view/selection~Selection|null} viewSelection\n\t */\n\t_handleMutations( mutations, viewSelection ) {\n\t\tnew MutationHandler( this.editor ).handle( mutations, viewSelection );\n\t}\n}\n\n/**\n * Helper class for translating DOM mutations into model changes.\n *\n * @private\n */\nclass MutationHandler {\n\t/**\n\t * Creates an instance of the mutation handler.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * Editor instance for which mutations are handled.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The editing controller.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/controller/editingcontroller~EditingController} #editing\n\t\t */\n\t\tthis.editing = this.editor.editing;\n\t}\n\n\t/**\n\t * Handles given mutations.\n\t *\n\t * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n\t * module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n\t * @param {module:engine/view/selection~Selection|null} viewSelection\n\t */\n\thandle( mutations, viewSelection ) {\n\t\tif ( containerChildrenMutated( mutations ) ) {\n\t\t\tthis._handleContainerChildrenMutations( mutations, viewSelection );\n\t\t} else {\n\t\t\tfor ( const mutation of mutations ) {\n\t\t\t\t// Fortunately it will never be both.\n\t\t\t\tthis._handleTextMutation( mutation, viewSelection );\n\t\t\t\tthis._handleTextNodeInsertion( mutation );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handles situations when container's children mutated during input. This can happen when\n\t * the browser is trying to \"fix\" DOM in certain situations. For example, when the user starts to type\n\t * in `<p><a href=\"\"><i>Link{}</i></a></p>`, the browser might change the order of elements\n\t * to `<p><i><a href=\"\">Link</a>x{}</i></p>`. A similar situation happens when the spell checker\n\t * replaces a word wrapped with `<strong>` with a word wrapped with a `<b>` element.\n\t *\n\t * To handle such situations, the common DOM ancestor of all mutations is converted to the model representation\n\t * and then compared with the current model to calculate the proper text change.\n\t *\n\t * Note: Single text node insertion is handled in {@link #_handleTextNodeInsertion} and text node mutation is handled\n\t * in {@link #_handleTextMutation}).\n\t *\n\t * @private\n\t * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n\t * module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n\t * @param {module:engine/view/selection~Selection|null} viewSelection\n\t */\n\t_handleContainerChildrenMutations( mutations, viewSelection ) {\n\t\t// Get common ancestor of all mutations.\n\t\tconst mutationsCommonAncestor = getMutationsContainer( mutations );\n\n\t\t// Quit if there is no common ancestor.\n\t\tif ( !mutationsCommonAncestor ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domConverter = this.editor.editing.view.domConverter;\n\n\t\t// Get common ancestor in DOM.\n\t\tconst domMutationCommonAncestor = domConverter.mapViewToDom( mutationsCommonAncestor );\n\n\t\tif ( !domMutationCommonAncestor ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Create fresh DomConverter so it will not use existing mapping and convert current DOM to model.\n\t\t// This wouldn't be needed if DomConverter would allow to create fresh view without checking any mappings.\n\t\tconst freshDomConverter = new DomConverter();\n\t\tconst modelFromCurrentDom = this.editor.data.toModel( freshDomConverter.domToView( domMutationCommonAncestor ) ).getChild( 0 );\n\n\t\t// Current model.\n\t\tconst currentModel = this.editor.editing.mapper.toModelElement( mutationsCommonAncestor );\n\n\t\t// Get children from both ancestors.\n\t\tconst modelFromDomChildren = Array.from( modelFromCurrentDom.getChildren() );\n\t\tconst currentModelChildren = Array.from( currentModel.getChildren() );\n\n\t\t// Skip situations when common ancestor has any elements (cause they are too hard).\n\t\tif ( !hasOnlyTextNodes( modelFromDomChildren ) || !hasOnlyTextNodes( currentModelChildren ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Replace &nbsp; inserted by the browser with normal space.\n\t\t// See comment in `_handleTextMutation`.\n\t\tconst newText = modelFromDomChildren.map( item => item.data ).join( '' ).replace( /\\u00A0/g, ' ' );\n\t\tconst oldText = currentModelChildren.map( item => item.data ).join( '' );\n\n\t\t// Do nothing if mutations created same text.\n\t\tif ( oldText === newText ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst diffResult = diff( oldText, newText );\n\n\t\tconst { firstChangeAt, insertions, deletions } = calculateChanges( diffResult );\n\n\t\t// Try setting new model selection according to passed view selection.\n\t\tlet modelSelectionRange = null;\n\n\t\tif ( viewSelection ) {\n\t\t\tmodelSelectionRange = this.editing.mapper.toModelRange( viewSelection.getFirstRange() );\n\t\t}\n\n\t\tconst insertText = newText.substr( firstChangeAt, insertions );\n\t\tconst removeRange = ModelRange.createFromParentsAndOffsets(\n\t\t\tcurrentModel,\n\t\t\tfirstChangeAt,\n\t\t\tcurrentModel,\n\t\t\tfirstChangeAt + deletions\n\t\t);\n\n\t\tthis.editor.execute( 'input', {\n\t\t\ttext: insertText,\n\t\t\trange: removeRange,\n\t\t\tresultRange: modelSelectionRange\n\t\t} );\n\t}\n\n\t_handleTextMutation( mutation, viewSelection ) {\n\t\tif ( mutation.type != 'text' ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Replace &nbsp; inserted by the browser with normal space.\n\t\t// We want only normal spaces in the model and in the view. Renderer and DOM Converter will be then responsible\n\t\t// for rendering consecutive spaces using &nbsp;, but the model and the view has to be clear.\n\t\t// Other feature may introduce inserting non-breakable space on specific key stroke (for example shift + space).\n\t\t// However then it will be handled outside of mutations, like enter key is.\n\t\t// The replacing is here because it has to be done before `diff` and `diffToChanges` functions, as they\n\t\t// take `newText` and compare it to (cleaned up) view.\n\t\t// It could also be done in mutation observer too, however if any outside plugin would like to\n\t\t// introduce additional events for mutations, they would get already cleaned up version (this may be good or not).\n\t\tconst newText = mutation.newText.replace( /\\u00A0/g, ' ' );\n\t\t// To have correct `diffResult`, we also compare view node text data with &nbsp; replaced by space.\n\t\tconst oldText = mutation.oldText.replace( /\\u00A0/g, ' ' );\n\n\t\tconst diffResult = diff( oldText, newText );\n\n\t\tconst { firstChangeAt, insertions, deletions } = calculateChanges( diffResult );\n\n\t\t// Try setting new model selection according to passed view selection.\n\t\tlet modelSelectionRange = null;\n\n\t\tif ( viewSelection ) {\n\t\t\tmodelSelectionRange = this.editing.mapper.toModelRange( viewSelection.getFirstRange() );\n\t\t}\n\n\t\t// Get the position in view and model where the changes will happen.\n\t\tconst viewPos = new ViewPosition( mutation.node, firstChangeAt );\n\t\tconst modelPos = this.editing.mapper.toModelPosition( viewPos );\n\t\tconst removeRange = ModelRange.createFromPositionAndShift( modelPos, deletions );\n\t\tconst insertText = newText.substr( firstChangeAt, insertions );\n\n\t\tthis.editor.execute( 'input', {\n\t\t\ttext: insertText,\n\t\t\trange: removeRange,\n\t\t\tresultRange: modelSelectionRange\n\t\t} );\n\t}\n\n\t_handleTextNodeInsertion( mutation ) {\n\t\tif ( mutation.type != 'children' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst change = getSingleTextNodeChange( mutation );\n\t\tconst viewPos = new ViewPosition( mutation.node, change.index );\n\t\tconst modelPos = this.editing.mapper.toModelPosition( viewPos );\n\t\tconst insertedText = change.values[ 0 ].data;\n\n\t\tthis.editor.execute( 'input', {\n\t\t\t// Replace &nbsp; inserted by the browser with normal space.\n\t\t\t// See comment in `_handleTextMutation`.\n\t\t\t// In this case we don't need to do this before `diff` because we diff whole nodes.\n\t\t\t// Just change &nbsp; in case there are some.\n\t\t\ttext: insertedText.replace( /\\u00A0/g, ' ' ),\n\t\t\trange: new ModelRange( modelPos )\n\t\t} );\n\t}\n}\n\nconst safeKeycodes = [\n\tgetCode( 'arrowUp' ),\n\tgetCode( 'arrowRight' ),\n\tgetCode( 'arrowDown' ),\n\tgetCode( 'arrowLeft' ),\n\t9, // Tab\n\t16, // Shift\n\t17, // Ctrl\n\t18, // Alt\n\t20, // CapsLock\n\t27, // Escape\n\t33, // PageUp\n\t34, // PageDown\n\t35, // Home\n\t36, // End\n\t229 // Composition start key\n];\n\n// Function keys.\nfor ( let code = 112; code <= 135; code++ ) {\n\tsafeKeycodes.push( code );\n}\n\n// Returns `true` if a keystroke should not cause any content change caused by \"typing\".\n//\n// Note: This implementation is very simple and will need to be refined with time.\n//\n// @private\n// @param {engine.view.observer.keyObserver.KeyEventData} keyData\n// @returns {Boolean}\nfunction isSafeKeystroke( keyData ) {\n\t// Keystrokes which contain Ctrl don't represent typing.\n\tif ( keyData.ctrlKey ) {\n\t\treturn true;\n\t}\n\n\treturn safeKeycodes.includes( keyData.keyCode );\n}\n\n// Helper function that compares whether two given view nodes are same. It is used in `diff` when it's passed an array\n// with child nodes.\nfunction compareChildNodes( oldChild, newChild ) {\n\tif ( oldChild instanceof ViewText && newChild instanceof ViewText ) {\n\t\treturn oldChild.data === newChild.data;\n\t} else {\n\t\treturn oldChild === newChild;\n\t}\n}\n\n// Returns change made to a single text node. Returns `undefined` if more than a single text node was changed.\n//\n// @private\n// @param mutation\nfunction getSingleTextNodeChange( mutation ) {\n\t// One new node.\n\tif ( mutation.newChildren.length - mutation.oldChildren.length != 1 ) {\n\t\treturn;\n\t}\n\n\t// Which is text.\n\tconst diffResult = diff( mutation.oldChildren, mutation.newChildren, compareChildNodes );\n\tconst changes = diffToChanges( diffResult, mutation.newChildren );\n\n\t// In case of [ delete, insert, insert ] the previous check will not exit.\n\tif ( changes.length > 1 ) {\n\t\treturn;\n\t}\n\n\tconst change = changes[ 0 ];\n\n\t// Which is text.\n\tif ( !( change.values[ 0 ] instanceof ViewText ) ) {\n\t\treturn;\n\t}\n\n\treturn change;\n}\n\n// Returns first common ancestor of all mutations that is either {@link module:engine/view/containerelement~ContainerElement}\n// or {@link module:engine/view/rootelement~RootElement}.\n//\n// @private\n// @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n// module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n// @returns {module:engine/view/containerelement~ContainerElement|engine/view/rootelement~RootElement|undefined}\nfunction getMutationsContainer( mutations ) {\n\tconst lca = mutations\n\t\t.map( mutation => mutation.node )\n\t\t.reduce( ( commonAncestor, node ) => {\n\t\t\treturn commonAncestor.getCommonAncestor( node, { includeSelf: true } );\n\t\t} );\n\n\tif ( !lca ) {\n\t\treturn;\n\t}\n\n\t// We need to look for container and root elements only, so check all LCA's\n\t// ancestors (starting from itself).\n\treturn lca.getAncestors( { includeSelf: true, parentFirst: true } )\n\t\t.find( element => element.is( 'containerElement' ) || element.is( 'rootElement' ) );\n}\n\n// Returns true if container children have mutated or more than a single text node was changed.\n//\n// Single text node child insertion is handled in {@link module:typing/input~MutationHandler#_handleTextNodeInsertion}\n// while text mutation is handled in {@link module:typing/input~MutationHandler#_handleTextMutation}.\n//\n// @private\n// @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n// module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n// @returns {Boolean}\nfunction containerChildrenMutated( mutations ) {\n\tif ( mutations.length == 0 ) {\n\t\treturn false;\n\t}\n\n\t// Check if there is any mutation of `children` type or any mutation that changes more than one text node.\n\tfor ( const mutation of mutations ) {\n\t\tif ( mutation.type === 'children' && !getSingleTextNodeChange( mutation ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n// Returns true if provided array contains only {@link module:engine/model/text~Text model text nodes}.\n//\n// @param {Array.<module:engine/model/node~Node>} children\n// @returns {Boolean}\nfunction hasOnlyTextNodes( children ) {\n\treturn children.every( child => child.is( 'text' ) );\n}\n\n// Calculates first change index and number of characters that should be inserted and deleted starting from that index.\n//\n// @private\n// @param diffResult\n// @return {{insertions: number, deletions: number, firstChangeAt: *}}\nfunction calculateChanges( diffResult ) {\n\t// Index where the first change happens. Used to set the position from which nodes will be removed and where will be inserted.\n\tlet firstChangeAt = null;\n\t// Index where the last change happens. Used to properly count how many characters have to be removed and inserted.\n\tlet lastChangeAt = null;\n\n\t// Get `firstChangeAt` and `lastChangeAt`.\n\tfor ( let i = 0; i < diffResult.length; i++ ) {\n\t\tconst change = diffResult[ i ];\n\n\t\tif ( change != 'equal' ) {\n\t\t\tfirstChangeAt = firstChangeAt === null ? i : firstChangeAt;\n\t\t\tlastChangeAt = i;\n\t\t}\n\t}\n\n\t// How many characters, starting from `firstChangeAt`, should be removed.\n\tlet deletions = 0;\n\t// How many characters, starting from `firstChangeAt`, should be inserted.\n\tlet insertions = 0;\n\n\tfor ( let i = firstChangeAt; i <= lastChangeAt; i++ ) {\n\t\t// If there is no change (equal) or delete, the character is existing in `oldText`. We count it for removing.\n\t\tif ( diffResult[ i ] != 'insert' ) {\n\t\t\tdeletions++;\n\t\t}\n\n\t\t// If there is no change (equal) or insert, the character is existing in `newText`. We count it for inserting.\n\t\tif ( diffResult[ i ] != 'delete' ) {\n\t\t\tinsertions++;\n\t\t}\n\t}\n\n\treturn { insertions, deletions, firstChangeAt };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-typing/src/input.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/deletecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport Selection from '@ckeditor/ckeditor5-engine/src/model/selection';\nimport Element from '@ckeditor/ckeditor5-engine/src/model/element';\nimport Position from '@ckeditor/ckeditor5-engine/src/model/position';\nimport Range from '@ckeditor/ckeditor5-engine/src/model/range';\nimport ChangeBuffer from './changebuffer';\nimport count from '@ckeditor/ckeditor5-utils/src/count';\n\n/**\n * The delete command. Used by the {@link module:typing/delete~Delete delete feature} to handle the <kbd>Delete</kbd> and\n * <kbd>Backspace</kbd> keys.\n *\n * @extends module:core/command~Command\n */\nexport default class DeleteCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {'forward'|'backward'} direction The directionality of the delete describing in what direction it\n\t * should consume the content when the selection is collapsed.\n\t */\n\tconstructor( editor, direction ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The directionality of the delete describing in what direction it should\n\t\t * consume the content when the selection is collapsed.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'forward'|'backward'} #direction\n\t\t */\n\t\tthis.direction = direction;\n\n\t\t/**\n\t\t * Delete's change buffer used to group subsequent changes into batches.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {typing.ChangeBuffer} #buffer\n\t\t */\n\t\tthis._buffer = new ChangeBuffer( editor.document, editor.config.get( 'typing.undoStep' ) );\n\t}\n\n\t/**\n\t * Executes the delete command. Depending on whether the selection is collapsed or not, deletes its content\n\t * or a piece of content in the {@link #direction defined direction}.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] The command options.\n\t * @param {'character'} [options.unit='character'] See {@link module:engine/controller/modifyselection~modifySelection}'s options.\n\t * @param {Number} [options.sequence=1] A number describing which subsequent delete event it is without the key being released.\n\t * See the {@link module:engine/view/document~Document#event:delete} event data.\n\t */\n\texecute( options = {} ) {\n\t\tconst doc = this.editor.document;\n\t\tconst dataController = this.editor.data;\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tthis._buffer.lock();\n\n\t\t\tconst selection = Selection.createFromSelection( doc.selection );\n\n\t\t\t// Do not replace the whole selected content if selection was collapsed.\n\t\t\t// This prevents such situation:\n\t\t\t//\n\t\t\t// <h1></h1><p>[]</p>\t--> <h1>[</h1><p>]</p> \t\t--> <p></p>\n\t\t\t// starting content\t\t--> after `modifySelection`\t--> after `deleteContent`.\n\t\t\tconst doNotResetEntireContent = selection.isCollapsed;\n\n\t\t\t// Try to extend the selection in the specified direction.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tdataController.modifySelection( selection, { direction: this.direction, unit: options.unit } );\n\t\t\t}\n\n\t\t\t// Check if deleting in an empty editor. See #61.\n\t\t\tif ( this._shouldEntireContentBeReplacedWithParagraph( options.sequence || 1 ) ) {\n\t\t\t\tthis._replaceEntireContentWithParagraph();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If selection is still collapsed, then there's nothing to delete.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet changeCount = 0;\n\n\t\t\tselection.getFirstRange().getMinimalFlatRanges().forEach( range => {\n\t\t\t\tchangeCount += count(\n\t\t\t\t\trange.getWalker( { singleCharacters: true, ignoreElementEnd: true, shallow: true } )\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tdataController.deleteContent( selection, this._buffer.batch, { doNotResetEntireContent } );\n\t\t\tthis._buffer.input( changeCount );\n\n\t\t\tdoc.selection.setRanges( selection.getRanges(), selection.isBackward );\n\n\t\t\tthis._buffer.unlock();\n\t\t} );\n\t}\n\n\t/**\n\t * If the user keeps <kbd>Backspace</kbd> or <kbd>Delete</kbd> key pressed, the content of the current\n\t * editable will be cleared. However, this will not yet lead to resetting the remaining block to a paragraph\n\t * (which happens e.g. when the user does <kbd>Ctrl</kbd> + <kbd>A</kbd>, <kbd>Backspace</kbd>).\n\t *\n\t * But, if the user pressed the key in an empty editable for the first time,\n\t * we want to replace the entire content with a paragraph if:\n\t *\n\t * * the current limit element is empty,\n\t * * the paragraph is allowed in the limit element,\n\t * * the limit doesn't already have a paragraph inside.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5-typing/issues/61.\n\t *\n\t * @private\n\t * @param {Number} sequence A number describing which subsequent delete event it is without the key being released.\n\t * @returns {Boolean}\n\t */\n\t_shouldEntireContentBeReplacedWithParagraph( sequence ) {\n\t\t// Does nothing if user pressed and held the \"Backspace\" or \"Delete\" key.\n\t\tif ( sequence > 1 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst document = this.editor.document;\n\t\tconst selection = document.selection;\n\t\tconst limitElement = document.schema.getLimitElement( selection );\n\n\t\t// If a collapsed selection contains the whole content it means that the content is empty\n\t\t// (from the user perspective).\n\t\tconst limitElementIsEmpty = selection.isCollapsed && selection.containsEntireContent( limitElement );\n\n\t\tif ( !limitElementIsEmpty ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !document.schema.check( { name: 'paragraph', inside: limitElement.name } ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst limitElementFirstChild = limitElement.getChild( 0 );\n\n\t\t// Does nothing if the limit element already contains only a paragraph.\n\t\t// We ignore the case when paragraph might have some inline elements (<p><inlineWidget>[]</inlineWidget></p>)\n\t\t// because we don't support such cases yet and it's unclear whether inlineWidget shouldn't be a limit itself.\n\t\tif ( limitElementFirstChild && limitElementFirstChild.name === 'paragraph' ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * The entire content is replaced with the paragraph. Selection is moved inside the paragraph.\n\t *\n\t * @private\n\t */\n\t_replaceEntireContentWithParagraph() {\n\t\tconst document = this.editor.document;\n\t\tconst selection = document.selection;\n\t\tconst limitElement = document.schema.getLimitElement( selection );\n\t\tconst paragraph = new Element( 'paragraph' );\n\n\t\tthis._buffer.batch.remove( Range.createIn( limitElement ) );\n\t\tthis._buffer.batch.insert( Position.createAt( limitElement ), paragraph );\n\n\t\tselection.setCollapsedAt( paragraph );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-typing/src/deletecommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/basecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\n/**\n * Base class for undo feature commands: {@link module:undo/undocommand~UndoCommand} and {@link module:undo/redocommand~RedoCommand}.\n *\n * @protected\n * @extends module:core/command~Command\n */\nexport default class BaseCommand extends Command {\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Stack of items stored by the command. These are pairs of:\n\t\t *\n\t\t * * {@link module:engine/model/batch~Batch batch} saved by the command,\n\t\t * * {@link module:engine/model/selection~Selection selection} state at the moment of saving the batch.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array} #_stack\n\t\t */\n\t\tthis._stack = [];\n\n\t\t/**\n\t\t * Stores all batches that were created by this command.\n\t\t *\n\t\t * @protected\n\t\t * @member {WeakSet.<module:engine/model/batch~Batch>} #_createdBatches\n\t\t */\n\t\tthis._createdBatches = new WeakSet();\n\n\t\t// Refresh state, so the command is inactive right after initialization.\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._stack.length > 0;\n\t}\n\n\t/**\n\t * Stores a batch in the command, together with the selection state of the {@link module:engine/model/document~Document document}\n\t * created by the editor which this command is registered to.\n\t *\n\t * @param {module:engine/model/batch~Batch} batch The batch to add.\n\t */\n\taddBatch( batch ) {\n\t\tconst docSelection = this.editor.document.selection;\n\n\t\tconst selection = {\n\t\t\tranges: docSelection.hasOwnRange ? Array.from( docSelection.getRanges() ) : [],\n\t\t\tisBackward: docSelection.isBackward\n\t\t};\n\n\t\tthis._stack.push( { batch, selection } );\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Removes all items from the stack.\n\t */\n\tclearStack() {\n\t\tthis._stack = [];\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Restores the {@link module:engine/model/document~Document#selection document selection} state after a batch was undone.\n\t *\n\t * @protected\n\t * @param {Array.<module:engine/model/range~Range>} ranges Ranges to be restored.\n\t * @param {Boolean} isBackward A flag describing whether the restored range was selected forward or backward.\n\t * @param {Array.<module:engine/model/delta/delta~Delta>} deltas Deltas which has been applied since selection has been stored.\n\t */\n\t_restoreSelection( ranges, isBackward, deltas ) {\n\t\tconst document = this.editor.document;\n\n\t\t// This will keep the transformed selection ranges.\n\t\tconst selectionRanges = [];\n\n\t\t// Transform all ranges from the restored selection.\n\t\tfor ( const range of ranges ) {\n\t\t\tconst transformedRanges = transformSelectionRange( range, deltas );\n\n\t\t\t// For each `range` from `ranges`, we take only one transformed range.\n\t\t\t// This is because we want to prevent situation where single-range selection\n\t\t\t// got transformed to multi-range selection. We will take the first range that\n\t\t\t// is not in the graveyard.\n\t\t\tconst transformedRange = transformedRanges.find(\n\t\t\t\trange => range.start.root != document.graveyard\n\t\t\t);\n\n\t\t\t// `transformedRange` might be `undefined` if transformed range ended up in graveyard.\n\t\t\tif ( transformedRange ) {\n\t\t\t\tselectionRanges.push( transformedRange );\n\t\t\t}\n\t\t}\n\n\t\t// `selectionRanges` may be empty if all ranges ended up in graveyard. If that is the case, do not restore selection.\n\t\tif ( selectionRanges.length ) {\n\t\t\tdocument.selection.setRanges( selectionRanges, isBackward );\n\t\t}\n\t}\n\n\t/**\n\t * Undoes a batch by reversing that batch, transforming reversed batch and finally applying it.\n\t * This is a helper method for {@link #execute}.\n\t *\n\t * @protected\n\t * @param {module:engine/model/batch~Batch} batchToUndo The batch to be undone.\n\t */\n\t_undo( batchToUndo ) {\n\t\tconst document = this.editor.document;\n\n\t\t// All changes done by the command execution will be saved as one batch.\n\t\tconst undoingBatch = document.batch();\n\t\tthis._createdBatches.add( undoingBatch );\n\n\t\tconst deltasToUndo = batchToUndo.deltas.slice();\n\t\tdeltasToUndo.reverse();\n\n\t\t// We will process each delta from `batchToUndo`, in reverse order. If there were deltas A, B and C in undone batch,\n\t\t// we need to revert them in reverse order, so first C' (reversed C), then B', then A'.\n\t\tfor ( const deltaToUndo of deltasToUndo ) {\n\t\t\t// Keep in mind that transformation algorithms return arrays. That's because the transformation might result in multiple\n\t\t\t// deltas, so we need arrays to handle them. To simplify algorithms, it is better to always operate on arrays.\n\t\t\tconst nextBaseVersion = deltaToUndo.baseVersion + deltaToUndo.operations.length;\n\n\t\t\t// Reverse delta from the history.\n\t\t\tconst historyDeltas = Array.from( document.history.getDeltas( nextBaseVersion ) );\n\t\t\tconst transformedSets = document.transformDeltas( [ deltaToUndo.getReversed() ], historyDeltas, true );\n\t\t\tconst reversedDeltas = transformedSets.deltasA;\n\n\t\t\t// After reversed delta has been transformed by all history deltas, apply it.\n\t\t\tfor ( const delta of reversedDeltas ) {\n\t\t\t\t// Fix base version.\n\t\t\t\tdelta.baseVersion = document.version;\n\n\t\t\t\t// Before applying, add the delta to the `undoingBatch`.\n\t\t\t\tundoingBatch.addDelta( delta );\n\n\t\t\t\t// Now, apply all operations of the delta.\n\t\t\t\tfor ( const operation of delta.operations ) {\n\t\t\t\t\tdocument.applyOperation( operation );\n\t\t\t\t}\n\n\t\t\t\tdocument.history.setDeltaAsUndone( deltaToUndo, delta );\n\t\t\t}\n\t\t}\n\n\t\treturn undoingBatch;\n\t}\n}\n\n// Transforms given range `range` by given `deltas`.\n// Returns an array containing one or more ranges, which are result of the transformation.\nfunction transformSelectionRange( range, deltas ) {\n\tconst transformed = transformRangesByDeltas( [ range ], deltas );\n\n\t// After `range` got transformed, we have an array of ranges. Some of those\n\t// ranges may be \"touching\" -- they can be next to each other and could be merged.\n\t// First, we have to sort those ranges to assure that they are in order.\n\ttransformed.sort( ( a, b ) => a.start.isBefore( b.start ) ? -1 : 1 );\n\n\t// Then, we check if two consecutive ranges are touching.\n\tfor ( let i = 1; i < transformed.length; i++ ) {\n\t\tconst a = transformed[ i - 1 ];\n\t\tconst b = transformed[ i ];\n\n\t\tif ( a.end.isTouching( b.start ) ) {\n\t\t\t// And join them together if they are.\n\t\t\ta.end = b.end;\n\t\t\ttransformed.splice( i, 1 );\n\t\t\ti--;\n\t\t}\n\t}\n\n\treturn transformed;\n}\n\n// Transforms given set of `ranges` by given set of `deltas`. Returns transformed `ranges`.\nexport function transformRangesByDeltas( ranges, deltas ) {\n\tfor ( const delta of deltas ) {\n\t\tfor ( const operation of delta.operations ) {\n\t\t\t// We look through all operations from all deltas.\n\n\t\t\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t\t\t// We transform every range by every operation.\n\t\t\t\tlet result;\n\n\t\t\t\tswitch ( operation.type ) {\n\t\t\t\t\tcase 'insert':\n\t\t\t\t\t\tresult = ranges[ i ]._getTransformedByInsertion(\n\t\t\t\t\t\t\toperation.position,\n\t\t\t\t\t\t\toperation.nodes.maxOffset,\n\t\t\t\t\t\t\ttrue\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'move':\n\t\t\t\t\tcase 'remove':\n\t\t\t\t\tcase 'reinsert':\n\t\t\t\t\t\tresult = ranges[ i ]._getTransformedByMove(\n\t\t\t\t\t\t\toperation.sourcePosition,\n\t\t\t\t\t\t\toperation.targetPosition,\n\t\t\t\t\t\t\toperation.howMany,\n\t\t\t\t\t\t\ttrue\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// If we have a transformation result, we substitute transformed range with it in `transformed` array.\n\t\t\t\t// Keep in mind that the result is an array and may contain multiple ranges.\n\t\t\t\tif ( result ) {\n\t\t\t\t\tranges.splice( i, 1, ...result );\n\n\t\t\t\t\t// Fix iterator.\n\t\t\t\t\ti = i + result.length - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ranges;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-undo/src/basecommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/undocommand\n */\n\nimport BaseCommand from './basecommand';\n\n/**\n * The undo command stores {@link module:engine/model/batch~Batch batches} applied to the\n * {@link module:engine/model/document~Document document} and is able to undo a batch by reversing it and transforming by\n * batches from {@link module:engine/model/document~Document#history history} that happened after the reversed batch.\n *\n * The undo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.\n *\n * @extends module:undo/basecommand~BaseCommand\n */\nexport default class UndoCommand extends BaseCommand {\n\t/**\n\t * Executes the command. This method reverts a {@link module:engine/model/batch~Batch batch} added to the command's stack, transforms\n\t * and applies the reverted version on the {@link module:engine/model/document~Document document} and removes the batch from the stack.\n\t * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.\n\t *\n\t * @fires execute\n\t * @fires revert\n\t * @param {module:engine/model/batch~Batch} [batch] A batch that should be undone. If not set, the last added batch will be undone.\n\t */\n\texecute( batch = null ) {\n\t\t// If batch is not given, set `batchIndex` to the last index in command stack.\n\t\tconst batchIndex = batch ? this._stack.findIndex( a => a.batch == batch ) : this._stack.length - 1;\n\n\t\tconst item = this._stack.splice( batchIndex, 1 )[ 0 ];\n\n\t\t// All changes has to be done in one `enqueueChanges` callback so other listeners will not\n\t\t// step between consecutive deltas, or won't do changes to the document before selection is properly restored.\n\t\tthis.editor.document.enqueueChanges( () => {\n\t\t\tconst undoingBatch = this._undo( item.batch );\n\n\t\t\tconst deltas = this.editor.document.history.getDeltas( item.batch.baseVersion );\n\t\t\tthis._restoreSelection( item.selection.ranges, item.selection.isBackward, deltas );\n\n\t\t\tthis.fire( 'revert', item.batch, undoingBatch );\n\t\t} );\n\n\t\tthis.refresh();\n\t}\n}\n\n/**\n * Fired when execution of the command reverts some batch.\n *\n * @event revert\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-undo/src/undocommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals window, document */\n\n/**\n * @module adapter-ckfinder/utils\n */\n\nconst TOKEN_COOKIE_NAME = 'ckCsrfToken';\nconst TOKEN_LENGTH = 40;\nconst tokenCharset = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\n/**\n * Returns the CSRF token value. The value is a hash stored in `document.cookie`\n * under the `ckCsrfToken` key. The CSRF token can be used to secure the communication\n * between the web browser and the CKFinder server.\n *\n * @returns {String}\n */\nexport function getCsrfToken() {\n\tlet token = getCookie( TOKEN_COOKIE_NAME );\n\n\tif ( !token || token.length != TOKEN_LENGTH ) {\n\t\ttoken = generateToken( TOKEN_LENGTH );\n\t\tsetCookie( TOKEN_COOKIE_NAME, token );\n\t}\n\n\treturn token;\n}\n\n/**\n * Returns the value of the cookie with a given name or `null` if the cookie is not found.\n *\n * @param {String} name\n * @returns {String|null}\n */\nexport function getCookie( name ) {\n\tname = name.toLowerCase();\n\tconst parts = document.cookie.split( ';' );\n\n\tfor ( const part of parts ) {\n\t\tconst pair = part.split( '=' );\n\t\tconst key = decodeURIComponent( pair[ 0 ].trim().toLowerCase() );\n\n\t\tif ( key === name ) {\n\t\t\treturn decodeURIComponent( pair[ 1 ] );\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Sets the value of the cookie with a given name.\n *\n * @param {String} name\n * @param {String} value\n */\nexport function setCookie( name, value ) {\n\tdocument.cookie = encodeURIComponent( name ) + '=' + encodeURIComponent( value ) + ';path=/';\n}\n\n// Generates the CSRF token with the given length.\n//\n// @private\n// @param {Number} length\n// @returns {string}\nfunction generateToken( length ) {\n\tlet result = '';\n\tconst randValues = new Uint8Array( length );\n\n\twindow.crypto.getRandomValues( randValues );\n\n\tfor ( let j = 0; j < randValues.length; j++ ) {\n\t\tconst character = tokenCharset.charAt( randValues[ j ] % tokenCharset.length );\n\t\tresult += Math.random() > 0.5 ? character.toUpperCase() : character;\n\t}\n\n\treturn result;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-adapter-ckfinder/src/utils.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/* globals XMLHttpRequest, FormData */\n/**\n * @module adapter-ckfinder/uploadadapter\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';\nimport { getCsrfToken } from './utils';\n/**\n * A plugin that enables CKFinder uploads in CKEditor 5.\n *\n * Configure the upload URL in\n * {@link module:adapter-ckfinder/uploadadapter~CKFinderAdapterConfig#uploadUrl `ckfinder.uploadUrl`}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class CKFinderUploadAdapter extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [FileRepository];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'CKFinderUploadAdapter';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const url = this.editor.config.get('ckfinder.uploadUrl');\n if (!url) {\n return;\n }\n // Register CKFinderAdapter\n this.editor.plugins.get(FileRepository).createAdapter = loader => new Adapter(loader, url, this.editor.t);\n }\n}\n/**\n * Upload adapter for CKFinder.\n *\n * @private\n * @implements module:upload/filerepository~Adapter\n */\nclass Adapter {\n /**\n\t * Creates a new adapter instance.\n\t *\n\t * @param {module:upload/filerepository~FileLoader} loader\n\t * @param {String} url\n\t * @param {module:utils/locale~Locale#t} t\n\t */\n constructor(loader, url, t) {\n /**\n\t\t * FileLoader instance to use during the upload.\n\t\t *\n\t\t * @member {module:upload/filerepository~FileLoader} #loader\n\t\t */\n this.loader = loader;\n /**\n\t\t * Upload URL.\n\t\t *\n\t\t * @member {String} #url\n\t\t */\n this.url = url;\n /**\n\t\t * Locale translation method.\n\t\t *\n\t\t * @member {module:utils/locale~Locale#t} #t\n\t\t */\n this.t = t;\n }\n /**\n\t * Starts the upload process.\n\t *\n\t * @see module:upload/filerepository~Adapter#upload\n\t * @returns {Promise}\n\t */\n upload() {\n return new Promise((resolve, reject) => {\n this._initRequest();\n this._initListeners(resolve, reject);\n this._sendRequest();\n });\n }\n /**\n\t * Aborts the upload process.\n\t *\n\t * @see module:upload/filerepository~Adapter#abort\n\t * @returns {Promise}\n\t */\n abort() {\n if (this.xhr) {\n this.xhr.abort();\n }\n }\n /**\n\t * Initializes the XMLHttpRequest object.\n\t *\n\t * @private\n\t */\n _initRequest() {\n const xhr = this.xhr = new XMLHttpRequest();\n xhr.open('POST', this.url, true);\n xhr.responseType = 'json';\n }\n /**\n\t * Initializes XMLHttpRequest listeners.\n\t *\n\t * @private\n\t * @param {Function} resolve Callback function to be called when the request is successful.\n\t * @param {Function} reject Callback function to be called when the request cannot be completed.\n\t */\n _initListeners(resolve, reject) {\n const xhr = this.xhr;\n const loader = this.loader;\n const t = this.t;\n const genericError = t('Cannot upload file:') + ` ${ loader.file.name }.`;\n xhr.addEventListener('error', () => reject(genericError));\n xhr.addEventListener('abort', () => reject());\n xhr.addEventListener('load', () => {\n const response = xhr.response;\n if (!response || !response.uploaded) {\n return reject(response && response.error && response.error.message ? response.error.message : genericError);\n }\n resolve({ default: response.url });\n });\n // Upload progress when it's supported.\n /* istanbul ignore else */\n if (xhr.upload) {\n xhr.upload.addEventListener('progress', evt => {\n if (evt.lengthComputable) {\n loader.uploadTotal = evt.total;\n loader.uploaded = evt.loaded;\n }\n });\n }\n }\n /**\n\t * Prepares the data and sends the request.\n\t *\n\t * @private\n\t */\n _sendRequest() {\n // Prepare form data.\n const data = new FormData();\n data.append('upload', this.loader.file);\n data.append('ckCsrfToken', getCsrfToken());\n // Send request.\n this.xhr.send(data);\n }\n} /**\n * The configuration of the {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter CKFinder upload adapter}.\n *\n * Read more in {@link module:adapter-ckfinder/uploadadapter~CKFinderAdapterConfig}.\n *\n * @member {module:adapter-ckfinder/uploadadapter~CKFinderAdapterConfig} module:core/editor/editorconfig~EditorConfig#ckfinder\n */\n /**\n * The configuration of the {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter CKFinder upload adapter}.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\tckfinder: {\n *\t\t\t\t\tuploadUrl: '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files&responseType=json'\n * \t\t\t\t}\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface CKFinderAdapterConfig\n */\n /**\n * The URL to which files should be uploaded.\n *\n * @member {String} module:adapter-ckfinder/uploadadapter~CKFinderAdapterConfig#uploadUrl\n */\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-adapter-ckfinder/src/uploadadapter.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module autoformat/inlineautoformatengine\n */\n\nimport LiveRange from '@ckeditor/ckeditor5-engine/src/model/liverange';\n\n/**\n * The inline autoformatting engine. It allows to format various inline patterns. For example,\n * it can be configured to make \"foo\" bold when typed `**foo**` (the `**` markers will be removed).\n *\n * The autoformatting operation is integrated with the undo manager,\n * so the autoformatting step can be undone if the user's intention was not to format the text.\n *\n * See the constructors documentation to learn how to create custom inline autoformatters. You can also use\n * the {@link module:autoformat/autoformat~Autoformat} feature which enables a set of default autoformatters\n * (lists, headings, bold and italic).\n */\nexport default class InlineAutoformatEngine {\n\t/**\n\t * Enables autoformatting mechanism for a given {@link module:core/editor/editor~Editor}.\n\t *\n\t * It formats the matched text by applying the given model attribute or by running the provided formatting callback.\n\t * On every change applied to the model the autoformatting engine checks the text on the left of the selection\n\t * and executes the provided action if the text matches given criteria (regular expression or callback).\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {Function|RegExp} testRegexpOrCallback The regular expression or callback to execute on text.\n\t * Provided regular expression *must* have three capture groups. The first and the third capture group\n\t * should match opening and closing delimiters. The second capture group should match the text to format.\n\t *\n\t *\t\t// Matches the `**bold text**` pattern.\n\t *\t\t// There are three capturing groups:\n\t *\t\t// - The first to match the starting `**` delimiter.\n\t *\t\t// - The second to match the text to format.\n\t *\t\t// - The third to match the ending `**` delimiter.\n\t *\t\tnew InlineAutoformatEngine( editor, /(\\*\\*)([^\\*]+?)(\\*\\*)$/g, 'bold' );\n\t *\n\t * When a function is provided instead of the regular expression, it will be executed with the text to match as a parameter.\n\t * The function should return proper \"ranges\" to delete and format.\n\t *\n\t *\t\t{\n\t *\t\t\tremove: [\n\t *\t\t\t\t[ 0, 1 ],\t// Remove the first letter from the given text.\n\t *\t\t\t\t[ 5, 6 ]\t// Remove the 6th letter from the given text.\n\t *\t\t\t],\n\t *\t\t\tformat: [\n\t *\t\t\t\t[ 1, 5 ]\t// Format all letters from 2nd to 5th.\n\t *\t\t\t]\n\t *\t\t}\n\t *\n\t * @param {Function|String} attributeOrCallback The name of attribute to apply on matching text or a callback for manual\n\t * formatting.\n\t *\n\t *\t\t// Use attribute name:\n\t *\t\tnew InlineAutoformatEngine( editor, /(\\*\\*)([^\\*]+?)(\\*\\*)$/g, 'bold' );\n\t *\n\t *\t\t// Use formatting callback:\n\t *\t\tnew InlineAutoformatEngine( editor, /(\\*\\*)([^\\*]+?)(\\*\\*)$/g, ( batch, validRanges ) => {\n\t *\t\t\tfor ( let range of validRanges ) {\n\t *\t\t\t\tbatch.setAttribute( range, command, true );\n\t *\t\t\t}\n\t *\t\t} );\n\t */\n\tconstructor( editor, testRegexpOrCallback, attributeOrCallback ) {\n\t\tlet regExp;\n\t\tlet command;\n\t\tlet testCallback;\n\t\tlet formatCallback;\n\n\t\tif ( testRegexpOrCallback instanceof RegExp ) {\n\t\t\tregExp = testRegexpOrCallback;\n\t\t} else {\n\t\t\ttestCallback = testRegexpOrCallback;\n\t\t}\n\n\t\tif ( typeof attributeOrCallback == 'string' ) {\n\t\t\tcommand = attributeOrCallback;\n\t\t} else {\n\t\t\tformatCallback = attributeOrCallback;\n\t\t}\n\n\t\t// A test callback run on changed text.\n\t\ttestCallback = testCallback || ( text => {\n\t\t\tlet result;\n\t\t\tconst remove = [];\n\t\t\tconst format = [];\n\n\t\t\twhile ( ( result = regExp.exec( text ) ) !== null ) {\n\t\t\t\t// There should be full match and 3 capture groups.\n\t\t\t\tif ( result && result.length < 4 ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tlet {\n\t\t\t\t\tindex,\n\t\t\t\t\t'1': leftDel,\n\t\t\t\t\t'2': content,\n\t\t\t\t\t'3': rightDel\n\t\t\t\t} = result;\n\n\t\t\t\t// Real matched string - there might be some non-capturing groups so we need to recalculate starting index.\n\t\t\t\tconst found = leftDel + content + rightDel;\n\t\t\t\tindex += result[ 0 ].length - found.length;\n\n\t\t\t\t// Start and End offsets of delimiters to remove.\n\t\t\t\tconst delStart = [\n\t\t\t\t\tindex,\n\t\t\t\t\tindex + leftDel.length\n\t\t\t\t];\n\t\t\t\tconst delEnd = [\n\t\t\t\t\tindex + leftDel.length + content.length,\n\t\t\t\t\tindex + leftDel.length + content.length + rightDel.length\n\t\t\t\t];\n\n\t\t\t\tremove.push( delStart );\n\t\t\t\tremove.push( delEnd );\n\n\t\t\t\tformat.push( [ index + leftDel.length, index + leftDel.length + content.length ] );\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tremove,\n\t\t\t\tformat\n\t\t\t};\n\t\t} );\n\n\t\t// A format callback run on matched text.\n\t\tformatCallback = formatCallback || ( ( batch, validRanges ) => {\n\t\t\tfor ( const range of validRanges ) {\n\t\t\t\tbatch.setAttribute( range, command, true );\n\t\t\t}\n\t\t} );\n\n\t\teditor.document.on( 'change', ( evt, type, changes, batch ) => {\n\t\t\tif ( batch.type == 'transparent' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( type !== 'insert' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selection = editor.document.selection;\n\n\t\t\tif ( !selection.isCollapsed || !selection.focus || !selection.focus.parent ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst block = selection.focus.parent;\n\t\t\tconst text = getText( block ).slice( 0, selection.focus.offset );\n\t\t\tconst ranges = testCallback( text );\n\t\t\tconst rangesToFormat = [];\n\n\t\t\t// Apply format before deleting text.\n\t\t\tranges.format.forEach( range => {\n\t\t\t\tif ( range[ 0 ] === undefined || range[ 1 ] === undefined ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\trangesToFormat.push( LiveRange.createFromParentsAndOffsets(\n\t\t\t\t\tblock, range[ 0 ],\n\t\t\t\t\tblock, range[ 1 ]\n\t\t\t\t) );\n\t\t\t} );\n\n\t\t\tconst rangesToRemove = [];\n\n\t\t\t// Reverse order to not mix the offsets while removing.\n\t\t\tranges.remove.slice().reverse().forEach( range => {\n\t\t\t\tif ( range[ 0 ] === undefined || range[ 1 ] === undefined ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\trangesToRemove.push( LiveRange.createFromParentsAndOffsets(\n\t\t\t\t\tblock, range[ 0 ],\n\t\t\t\t\tblock, range[ 1 ]\n\t\t\t\t) );\n\t\t\t} );\n\n\t\t\tif ( !( rangesToFormat.length && rangesToRemove.length ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.document.enqueueChanges( () => {\n\t\t\t\t// Create new batch to separate typing batch from the Autoformat changes.\n\t\t\t\tconst fixBatch = editor.document.batch();\n\n\t\t\t\tconst validRanges = editor.document.schema.getValidRanges( rangesToFormat, command );\n\n\t\t\t\t// Apply format.\n\t\t\t\tformatCallback( fixBatch, validRanges );\n\n\t\t\t\t// Detach ranges used to apply Autoformat. Prevents memory leaks. #39\n\t\t\t\trangesToFormat.forEach( range => range.detach() );\n\n\t\t\t\t// Remove delimiters.\n\t\t\t\tfor ( const range of rangesToRemove ) {\n\t\t\t\t\tfixBatch.remove( range );\n\n\t\t\t\t\t// Prevents memory leaks.\n\t\t\t\t\t// https://github.com/ckeditor/ckeditor5-autoformat/issues/39\n\t\t\t\t\trange.detach();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n}\n\n// Returns whole text from parent element by adding all data from text nodes together.\n//\n// @private\n// @param {module:engine/model/element~Element} element\n// @returns {String}\nfunction getText( element ) {\n\treturn Array.from( element.getChildren() ).reduce( ( a, b ) => a + b.data, '' );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-autoformat/src/inlineautoformatengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module autoformat/autoformat\n */\n\nimport BlockAutoformatEngine from './blockautoformatengine';\nimport InlineAutoformatEngine from './inlineautoformatengine';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * Includes a set of predefined autoformatting actions. For a detailed overview, check\n * the {@glink features/autoformat Autoformatting feature documentation}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Autoformat extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Autoformat';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tthis._addListAutoformats();\n\t\tthis._addBasicStylesAutoformats();\n\t\tthis._addHeadingAutoformats();\n\t\tthis._addBlockQuoteAutoformats();\n\t}\n\n\t/**\n\t * Adds autoformatting related to the {@link module:list/list~List}.\n\t *\n\t * When typed:\n\t * - `* ` or `- ` &ndash; A paragraph will be changed to a bulleted list.\n\t * - `1. ` or `1) ` &ndash; A paragraph will be changed to a numbered list (\"1\" can be any digit or a list of digits).\n\t *\n\t * @private\n\t */\n\t_addListAutoformats() {\n\t\tconst commands = this.editor.commands;\n\n\t\tif ( commands.get( 'bulletedList' ) ) {\n\t\t\t// eslint-disable-next-line no-new\n\t\t\tnew BlockAutoformatEngine( this.editor, /^[*-]\\s$/, 'bulletedList' );\n\t\t}\n\n\t\tif ( commands.get( 'numberedList' ) ) {\n\t\t\t// eslint-disable-next-line no-new\n\t\t\tnew BlockAutoformatEngine( this.editor, /^\\d+[.|)]?\\s$/, 'numberedList' );\n\t\t}\n\t}\n\n\t/**\n\t * Adds autoformatting related to the {@link module:basic-styles/bold~Bold},\n\t * {@link module:basic-styles/italic~Italic} and {@link module:basic-styles/code~Code}.\n\t *\n\t * When typed:\n\t * - `**foobar**` &ndash; `**` characters are removed and `foobar` is set to bold,\n\t * - `__foobar__` &ndash; `__` characters are removed and `foobar` is set to bold,\n\t * - `*foobar*` &ndash; `*` characters are removed and `foobar` is set to italic,\n\t * - `_foobar_` &ndash; `_` characters are removed and `foobar` is set to italic,\n\t * - ``` `foobar` &ndash; ``` ` ``` characters are removed and `foobar` is set to code.\n\t *\n\t * @private\n\t */\n\t_addBasicStylesAutoformats() {\n\t\tconst commands = this.editor.commands;\n\n\t\tif ( commands.get( 'bold' ) ) {\n\t\t\t/* eslint-disable no-new */\n\t\t\tnew InlineAutoformatEngine( this.editor, /(\\*\\*)([^*]+)(\\*\\*)$/g, 'bold' );\n\t\t\tnew InlineAutoformatEngine( this.editor, /(__)([^_]+)(__)$/g, 'bold' );\n\t\t\t/* eslint-enable no-new */\n\t\t}\n\n\t\tif ( commands.get( 'italic' ) ) {\n\t\t\t// The italic autoformatter cannot be triggered by the bold markers, so we need to check the\n\t\t\t// text before the pattern (e.g. `(?:^|[^\\*])`).\n\n\t\t\t/* eslint-disable no-new */\n\t\t\tnew InlineAutoformatEngine( this.editor, /(?:^|[^*])(\\*)([^*_]+)(\\*)$/g, 'italic' );\n\t\t\tnew InlineAutoformatEngine( this.editor, /(?:^|[^_])(_)([^_]+)(_)$/g, 'italic' );\n\t\t\t/* eslint-enable no-new */\n\t\t}\n\n\t\tif ( commands.get( 'code' ) ) {\n\t\t\t/* eslint-disable no-new */\n\t\t\tnew InlineAutoformatEngine( this.editor, /(`)([^`]+)(`)$/g, 'code' );\n\t\t\t/* eslint-enable no-new */\n\t\t}\n\t}\n\n\t/**\n\t * Adds autoformatting related to {@link module:heading/heading~Heading}.\n\t *\n\t * It is using a number at the end of the command name to associate it with the proper trigger:\n\t *\n\t * * `heading1` will be executed when typing `#`,\n\t * * `heading2` will be executed when typing `##`,\n\t * * ... up to `heading6` and `######`.\n\t *\n\t * @private\n\t */\n\t_addHeadingAutoformats() {\n\t\tArray.from( this.editor.commands.names() )\n\t\t\t.filter( name => name.match( /^heading[1-6]$/ ) )\n\t\t\t.forEach( commandName => {\n\t\t\t\tconst level = commandName[ 7 ];\n\t\t\t\tconst pattern = new RegExp( `^(#{${ level }})\\\\s$` );\n\n\t\t\t\t// eslint-disable-next-line no-new\n\t\t\t\tnew BlockAutoformatEngine( this.editor, pattern, context => {\n\t\t\t\t\tconst { batch } = context;\n\n\t\t\t\t\tthis.editor.execute( commandName, { batch } );\n\t\t\t\t} );\n\t\t\t} );\n\t}\n\n\t/**\n\t * Adds autoformatting related to {@link module:block-quote/blockquote~BlockQuote}.\n\t *\n\t * When typed:\n\t * * `> ` &ndash; A paragraph will be changed to a block quote.\n\t *\n\t * @private\n\t */\n\t_addBlockQuoteAutoformats() {\n\t\tif ( this.editor.commands.get( 'blockQuote' ) ) {\n\t\t\t// eslint-disable-next-line no-new\n\t\t\tnew BlockAutoformatEngine( this.editor, /^>\\s$/, 'blockQuote' );\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-autoformat/src/autoformat.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/buildmodelconverter\n */\n\nimport {\n\tinsertElement,\n\tinsertUIElement,\n\tsetAttribute,\n\tremoveAttribute,\n\tremoveUIElement,\n\twrapItem,\n\tunwrapItem,\n\thighlightText,\n\thighlightElement\n} from './model-to-view-converters';\n\nimport { convertSelectionAttribute, convertSelectionMarker } from './model-selection-to-view-converters';\n\nimport ViewAttributeElement from '../view/attributeelement';\nimport ViewContainerElement from '../view/containerelement';\nimport ViewUIElement from '../view/uielement';\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Provides chainable, high-level API to easily build basic model-to-view converters that are appended to given\n * dispatchers. In many cases, this is the API that should be used to specify how abstract model elements and\n * attributes should be represented in the view (and then later in DOM). Instances of this class are created by\n * {@link module:engine/conversion/buildmodelconverter~buildModelConverter}.\n *\n * If you need more complex converters, see {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher},\n * {@link module:engine/conversion/model-to-view-converters}, {@link module:engine/conversion/modelconsumable~ModelConsumable},\n * {@link module:engine/conversion/mapper~Mapper}.\n *\n * Using this API it is possible to create five kinds of converters:\n *\n * 1. Model element to view element converter. This is a converter that takes the model element and represents it\n * in the view.\n *\n *\t\tbuildModelConverter().for( dispatcher ).fromElement( 'paragraph' ).toElement( 'p' );\n *\t\tbuildModelConverter().for( dispatcher ).fromElement( 'image' ).toElement( 'img' );\n *\n * 2. Model attribute to view attribute converter. This is a converter that operates on model element attributes\n * and converts them to view element attributes. It is suitable for elements like `image` (`src`, `title` attributes).\n *\n *\t\tbuildModelConverter().for( dispatcher ).fromElement( 'image' ).toElement( 'img' );\n *\t\tbuildModelConverter().for( dispatcher ).fromAttribute( 'src' ).toAttribute();\n *\n * 3. Model attribute to view element converter. This is a converter that takes model attributes and represents them\n * as view elements. Elements created by this kind of converter are wrapping other view elements. Wrapped view nodes\n * correspond to model nodes had converter attribute. It is suitable for attributes like `bold`, where `bold` attribute\n * set on model text nodes is converter to `strong` view element.\n *\n *\t\tbuildModelConverter().for( dispatcher ).fromAttribute( 'bold' ).toElement( 'strong' );\n *\n * 4. Model marker to view highlight converter. This is a converter that converts model markers to view highlight\n * described by {@link module:engine/conversion/model-to-view-converters~HighlightDescriptor} object passed to\n * {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder#toHighlight} method.\n *\n *\t\tbuildModelConverter().for( dispatcher ).fromMarker( 'search' ).toHighlight( {\n *\t\t\tclass: 'search',\n *\t\t\tpriority: 20\n *\t\t} );\n *\n * 5. Model marker to element converter. This is a converter that takes model marker and creates separate elements at\n * the beginning and at the end of the marker's range. For more information see\n * {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder#toElement} method.\n *\n *\t\tbuildModelConverter().for( dispatcher ).fromMarker( 'search' ).toElement( 'span' );\n *\n * It is possible to provide various different parameters for\n * {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder#toElement},\n * {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder#toAttribute} and\n * {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder#toHighlight} methods.\n * See their descriptions to learn more.\n *\n * It is also possible to {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder#withPriority change default priority}\n * of created converters to decide which converter should be fired earlier and which later. This is useful if you have\n * a general converter but also want to provide different special-case converters (i.e. given model element is converted\n * always to given view element, but if it has given attribute it is converter to other view element). For this,\n * use {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder#withPriority withPriority} right after `from...` method.\n *\n * Note that `to...` methods are \"terminators\", which means that should be the last one used in building converter.\n *\n * You can use {@link module:engine/conversion/buildviewconverter~ViewConverterBuilder}\n * to create \"opposite\" converters - from view to model.\n */\nclass ModelConverterBuilder {\n\t/**\n\t * Creates `ModelConverterBuilder` with given `dispatchers` registered to it.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Dispatchers to which converters will be attached.\n\t\t *\n\t\t * @type {Array.<module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher>}\n\t\t * @private\n\t\t */\n\t\tthis._dispatchers = [];\n\n\t\t/**\n\t\t * Contains data about registered \"from\" query.\n\t\t *\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._from = null;\n\t}\n\n\t/**\n\t * Set one or more dispatchers which the built converter will be attached to.\n\t *\n\t * @chainable\n\t * @param {...module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher} dispatchers One or more dispatchers.\n\t * @returns {module:engine/conversion/buildmodelconverter~ModelConverterBuilder}\n\t */\n\tfor( ...dispatchers ) {\n\t\tthis._dispatchers = dispatchers;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Registers what model element should be converted.\n\t *\n\t * @chainable\n\t * @param {String} elementName Name of element to convert.\n\t * @returns {module:engine/conversion/buildmodelconverter~ModelConverterBuilder}\n\t */\n\tfromElement( elementName ) {\n\t\tthis._from = {\n\t\t\ttype: 'element',\n\t\t\tname: elementName,\n\t\t\tpriority: null\n\t\t};\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Registers what model attribute should be converted.\n\t *\n\t * @chainable\n\t * @param {String} key Key of attribute to convert.\n\t * @returns {module:engine/conversion/buildmodelconverter~ModelConverterBuilder}\n\t */\n\tfromAttribute( key ) {\n\t\tthis._from = {\n\t\t\ttype: 'attribute',\n\t\t\tkey,\n\t\t\tpriority: null\n\t\t};\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Registers what type of marker should be converted.\n\t *\n\t * @chainable\n\t * @param {String} markerName Name of marker to convert.\n\t * @returns {module:engine/conversion/buildmodelconverter~ModelConverterBuilder}\n\t */\n\tfromMarker( markerName ) {\n\t\tthis._from = {\n\t\t\ttype: 'marker',\n\t\t\tname: markerName,\n\t\t\tpriority: null\n\t\t};\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Changes default priority for built converter. The lower the number, the earlier converter will be fired.\n\t * Default priority is `10`.\n\t *\n\t * **Note:** Keep in mind that event priority, that is set by this modifier, is used for attribute priority\n\t * when {@link module:engine/view/writer~writer} is used. This changes how view elements are ordered,\n\t * i.e.: `<strong><em>foo</em></strong>` vs `<em><strong>foo</strong></em>`. Using priority you can also\n\t * prevent node merging, i.e.: `<span class=\"bold\"><span class=\"theme\">foo</span><span>` vs `<span class=\"bold theme\">foo</span>`.\n\t * If you want to prevent merging, just set different priority for both converters.\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromAttribute( 'bold' ).withPriority( 2 ).toElement( 'strong' );\n\t *\t\tbuildModelConverter().for( dispatcher ).fromAttribute( 'italic' ).withPriority( 3 ).toElement( 'em' );\n\t *\n\t * @chainable\n\t * @param {Number} priority Converter priority.\n\t * @returns {module:engine/conversion/buildmodelconverter~ModelConverterBuilder}\n\t */\n\twithPriority( priority ) {\n\t\tthis._from.priority = priority;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Registers what view element will be created by converter.\n\t *\n\t * Method accepts various ways of providing how the view element will be created. You can pass view element name as\n\t * `string`, view element instance which will be cloned and used, or creator function which returns view element that\n\t * will be used. Keep in mind that when you view element instance or creator function, it has to be/return a\n\t * proper type of view element: {@link module:engine/view/containerelement~ContainerElement ViewContainerElement} if you convert\n\t * from element, {@link module:engine/view/attributeelement~AttributeElement ViewAttributeElement} if you convert\n\t * from attribute and {@link module:engine/view/uielement~UIElement ViewUIElement} if you convert from marker.\n\t *\n\t * **Note:** When converting from model's marker, separate elements will be created at the beginning and at the end of the\n\t * marker's range. If range is collapsed then only one element will be created. See how markers\n\t * {module:engine/model/buildviewconverter~ViewConverterBuilder#toMarker serialization from view to model}\n\t * works to find out what view element format is the best for you.\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromElement( 'paragraph' ).toElement( 'p' );\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromElement( 'image' ).toElement( new ViewContainerElement( 'img' ) );\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher )\n\t *\t\t\t.fromElement( 'header' )\n\t *\t\t\t.toElement( ( data ) => new ViewContainerElement( 'h' + data.item.getAttribute( 'level' ) ) );\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromAttribute( 'bold' ).toElement( new ViewAttributeElement( 'strong' ) );\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromMarker( 'search' ).toElement( 'span' );\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromMarker( 'search' ).toElement( new ViewUIElement( 'span' ) );\n\t *\n\t * Creator function will be passed different values depending whether conversion is from element or from attribute:\n\t *\n\t * * from element: dispatcher's\n\t * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:insert insert event}\n\t * parameters will be passed,\n\t * * from attribute: there is one parameter and it is attribute value,\n\t * * from marker: {@link module:engine/conversion/buildmodelconverter~MarkerViewElementCreatorData}.\n\t *\n\t * This method also registers model selection to view selection converter, if conversion is from attribute.\n\t *\n\t * This method creates the converter and adds it as a callback to a proper\n\t * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher conversion dispatcher} event.\n\t *\n\t * @param {String|module:engine/view/element~Element|Function} element Element created by converter or\n\t * a function that returns view element.\n\t */\n\ttoElement( element ) {\n\t\tconst priority = this._from.priority === null ? 'normal' : this._from.priority;\n\n\t\tfor ( const dispatcher of this._dispatchers ) {\n\t\t\tif ( this._from.type == 'element' ) {\n\t\t\t\t// From model element to view element -> insert element.\n\t\t\t\telement = typeof element == 'string' ? new ViewContainerElement( element ) : element;\n\n\t\t\t\tdispatcher.on( 'insert:' + this._from.name, insertElement( element ), { priority } );\n\t\t\t} else if ( this._from.type == 'attribute' ) {\n\t\t\t\t// From model attribute to view element -> wrap and unwrap.\n\t\t\t\telement = typeof element == 'string' ? new ViewAttributeElement( element ) : element;\n\n\t\t\t\tdispatcher.on( 'addAttribute:' + this._from.key, wrapItem( element ), { priority } );\n\t\t\t\tdispatcher.on( 'changeAttribute:' + this._from.key, wrapItem( element ), { priority } );\n\t\t\t\tdispatcher.on( 'removeAttribute:' + this._from.key, unwrapItem( element ), { priority } );\n\n\t\t\t\tdispatcher.on( 'selectionAttribute:' + this._from.key, convertSelectionAttribute( element ), { priority } );\n\t\t\t} else { // From marker to element.\n\t\t\t\tconst priority = this._from.priority === null ? 'normal' : this._from.priority;\n\n\t\t\t\telement = typeof element == 'string' ? new ViewUIElement( element ) : element;\n\n\t\t\t\tdispatcher.on( 'addMarker:' + this._from.name, insertUIElement( element ), { priority } );\n\t\t\t\tdispatcher.on( 'removeMarker:' + this._from.name, removeUIElement( element ), { priority } );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Registers that marker should be converted to view highlight. Markers, basically,\n\t * are {@link module:engine/model/liverange~LiveRange} instances, that are named. View highlight is\n\t * a representation of the model marker in the view:\n\t * * each {@link module:engine/view/text~Text view text node} in the marker's range will be wrapped with `span`\n\t * {@link module:engine/view/attributeelement~AttributeElement},\n\t * * each {@link module:engine/view/containerelement~ContainerElement container view element} in the marker's\n\t * range can handle highlighting individually by providing `addHighlight` and `removeHighlight`\n\t * custom properties:\n\t *\n\t *\t\tviewElement.setCustomProperty( 'addHighlight', ( element, descriptor ) => {} );\n\t *\t\tviewElement.setCustomProperty( 'removeHighlight', ( element, descriptorId ) => {} );\n\t *\n\t * {@link module:engine/conversion/model-to-view-converters~HighlightDescriptor} will be used to create\n\t * spans over text nodes and also will be provided to `addHighlight` and `removeHighlight` methods\n\t * each time highlight should be set or removed from view elements.\n\t *\n\t * **Note:** When `addHighlight` and `removeHighlight` custom properties are present, converter assumes\n\t * that element itself is taking care of presenting highlight on its child nodes, so it won't convert them.\n\t *\n\t * Highlight descriptor can be provided as plain object:\n\t *\n\t *\t\tbuildModelConverter.for( dispatcher ).fromMarker( 'search' ).toHighlight( { class: 'search-highlight' } );\n \t *\n\t * Also, descriptor creator function can be provided:\n\t *\n\t *\t\tbuildModelConverter.for( dispatcher ).fromMarker( 'search:blue' ).toHighlight( data => {\n\t *\t\t\tconst color = data.markerName.split( ':' )[ 1 ];\n\t *\n\t *\t\t\treturn { class: 'search-' + color };\n\t *\t\t} );\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * `build-model-converter-non-marker-to-highlight` when trying to convert not from marker.\n\t *\n\t * @param {function|module:engine/conversion/model-to-view-converters~HighlightDescriptor} highlightDescriptor\n\t */\n\ttoHighlight( highlightDescriptor ) {\n\t\tconst priority = this._from.priority === null ? 'normal' : this._from.priority;\n\n\t\tif ( this._from.type != 'marker' ) {\n\t\t\t/**\n\t\t\t * Conversion to a highlight is supported only from model markers.\n\t\t\t *\n\t\t\t * @error build-model-converter-non-marker-to-highlight\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'build-model-converter-non-marker-to-highlight: Conversion to a highlight is supported ' +\n\t\t\t\t'only from model markers.'\n\t\t\t);\n\t\t}\n\n\t\tfor ( const dispatcher of this._dispatchers ) {\n\t\t\t// Separate converters for converting texts and elements inside marker's range.\n\t\t\tdispatcher.on( 'addMarker:' + this._from.name, highlightText( highlightDescriptor ), { priority } );\n\t\t\tdispatcher.on( 'addMarker:' + this._from.name, highlightElement( highlightDescriptor ), { priority } );\n\n\t\t\tdispatcher.on( 'removeMarker:' + this._from.name, highlightText( highlightDescriptor ), { priority } );\n\t\t\tdispatcher.on( 'removeMarker:' + this._from.name, highlightElement( highlightDescriptor ), { priority } );\n\n\t\t\tdispatcher.on( 'selectionMarker:' + this._from.name, convertSelectionMarker( highlightDescriptor ), { priority } );\n\t\t}\n\t}\n\n\t/**\n\t * Registers what view attribute will be created by converter. Keep in mind, that only model attribute to\n\t * view attribute conversion is supported.\n\t *\n\t * Method accepts various ways of providing how the view attribute will be created:\n\t *\n\t * * for no passed parameter, attribute key and value will be converted 1-to-1 to view attribute,\n\t * * if you pass one `string`, it will be used as new attribute key while attribute value will be copied,\n\t * * if you pass two `string`s, first one will be used as new attribute key and second one as new attribute value,\n\t * * if you pass a function, it is expected to return an object with `key` and `value` properties representing attribute key and value.\n\t * This function will be passed model attribute value and model attribute key as first two parameters and then\n\t * all dispatcher's\n\t * {module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:changeAttribute changeAttribute event}\n\t * parameters.\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromAttribute( 'class' ).toAttribute( '' );\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromAttribute( 'linkTitle' ).toAttribute( 'title' );\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher ).fromAttribute( 'highlighted' ).toAttribute( 'style', 'background:yellow' );\n\t *\n\t *\t\tbuildModelConverter().for( dispatcher )\n\t *\t\t\t.fromAttribute( 'theme' )\n\t *\t\t\t.toAttribute( ( value ) => ( { key: 'class', value: value + '-theme' } ) );\n\t *\n\t * This method creates the converter and adds it as a callback to a proper\n\t * {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher conversion dispatcher} event.\n\t *\n\t * @param {String|Function} [keyOrCreator] Attribute key or a creator function.\n\t * @param {*} [value] Attribute value.\n\t */\n\ttoAttribute( keyOrCreator, value ) {\n\t\tif ( this._from.type != 'attribute' ) {\n\t\t\t/**\n\t\t\t * To-attribute conversion is supported only for model attributes.\n\t\t\t *\n\t\t\t * @error build-model-converter-element-to-attribute\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'build-model-converter-non-attribute-to-attribute: ' +\n\t\t\t\t'To-attribute conversion is supported only from model attributes.' );\n\t\t}\n\n\t\tlet attributeCreator;\n\n\t\tif ( !keyOrCreator ) {\n\t\t\t// If `keyOrCreator` is not set, we assume default behavior which is 1:1 attribute re-write.\n\t\t\t// This is also a default behavior for `setAttribute` converter when no attribute creator is passed.\n\t\t\tattributeCreator = undefined;\n\t\t} else if ( typeof keyOrCreator == 'string' ) {\n\t\t\t// `keyOrCreator` is an attribute key.\n\n\t\t\tif ( value ) {\n\t\t\t\t// If value is set, create \"dumb\" creator that always returns the same object.\n\t\t\t\tattributeCreator = function() {\n\t\t\t\t\treturn { key: keyOrCreator, value };\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\t// If value is not set, take it from the passed parameter.\n\t\t\t\tattributeCreator = function( value ) {\n\t\t\t\t\treturn { key: keyOrCreator, value };\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\t// `keyOrCreator` is an attribute creator function.\n\t\t\tattributeCreator = keyOrCreator;\n\t\t}\n\n\t\tfor ( const dispatcher of this._dispatchers ) {\n\t\t\tconst options = { priority: this._from.priority || 'normal' };\n\n\t\t\tdispatcher.on( 'addAttribute:' + this._from.key, setAttribute( attributeCreator ), options );\n\t\t\tdispatcher.on( 'changeAttribute:' + this._from.key, setAttribute( attributeCreator ), options );\n\t\t\tdispatcher.on( 'removeAttribute:' + this._from.key, removeAttribute( attributeCreator ), options );\n\t\t}\n\t}\n}\n\n/**\n * Entry point for model-to-view converters builder. This chainable API makes it easy to create basic, most common\n * model-to-view converters and attach them to provided dispatchers. The method returns an instance of\n * {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder}.\n */\nexport default function buildModelConverter() {\n\treturn new ModelConverterBuilder();\n}\n\n/**\n * @typedef {Object} module:engine/conversion/buildmodelconverter~MarkerViewElementCreatorData\n *\n * @param {String} markerName Marker name.\n * @param {module:engine/model/range~Range} markerRange Marker range.\n * @param {Boolean} isOpening Defines if currently converted element is a beginning or end of the marker range.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/buildmodelconverter.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/buildviewconverter\n */\n\nimport Matcher from '../view/matcher';\nimport ModelElement from '../model/element';\nimport ModelPosition from '../model/position';\nimport modelWriter from '../model/writer';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * Provides chainable, high-level API to easily build basic view-to-model converters that are appended to given\n * dispatchers. View-to-model converters are used when external data is added to the editor, i.e. when a user pastes\n * HTML content to the editor. Then, converters are used to translate this structure, possibly removing unknown/incorrect\n * nodes, and add it to the model. Also multiple, different elements might be translated into the same thing in the\n * model, i.e. `<b>` and `<strong>` elements might be converted to `bold` attribute (even though `bold` attribute will\n * be then converted only to `<strong>` tag). Instances of this class are created by\n * {@link module:engine/conversion/buildviewconverter~buildViewConverter}.\n *\n * If you need more complex converters, see {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher},\n * {@link module:engine/conversion/view-to-model-converters}, {@link module:engine/conversion/viewconsumable~ViewConsumable}.\n *\n * Using this API it is possible to create various kind of converters:\n *\n * 1. View element to model element:\n *\n *\t\tbuildViewConverter().for( dispatcher ).fromElement( 'p' ).toElement( 'paragraph' );\n *\n * 2. View element to model attribute:\n *\n *\t\tbuildViewConverter().for( dispatcher ).fromElement( 'b' ).fromElement( 'strong' ).toAttribute( 'bold', 'true' );\n *\n * 3. View attribute to model attribute:\n *\n *\t\tbuildViewConverter().for( dispatcher ).fromAttribute( 'style', { 'font-weight': 'bold' } ).toAttribute( 'bold', 'true' );\n *\t\tbuildViewConverter().for( dispatcher )\n *\t\t\t.fromAttribute( 'class' )\n *\t\t\t.toAttribute( ( viewElement ) => ( { class: viewElement.getAttribute( 'class' ) } ) );\n *\n * 4. View elements and attributes to model attribute:\n *\n *\t\tbuildViewConverter().for( dispatcher )\n *\t\t\t.fromElement( 'b' ).fromElement( 'strong' ).fromAttribute( 'style', { 'font-weight': 'bold' } )\n *\t\t\t.toAttribute( 'bold', 'true' );\n *\n * 5. View {@link module:engine/view/matcher~Matcher view element matcher instance} or\n * {@link module:engine/view/matcher~Matcher#add matcher pattern}\n * to model element or attribute:\n *\n *\t\tconst matcher = new ViewMatcher();\n *\t\tmatcher.add( 'div', { class: 'quote' } );\n *\t\tbuildViewConverter().for( dispatcher ).from( matcher ).toElement( 'quote' );\n *\n *\t\tbuildViewConverter().for( dispatcher ).from( { name: 'span', class: 'bold' } ).toAttribute( 'bold', 'true' );\n *\n * Note, that converters built using `ViewConverterBuilder` automatically check {@link module:engine/model/schema~Schema schema}\n * if created model structure is valid. If given conversion would be invalid according to schema, it is ignored.\n *\n * It is possible to provide creator functions as parameters for {@link ~ViewConverterBuilder#toElement}\n * and {@link module:engine/conversion/buildviewconverter~ViewConverterBuilder#toAttribute} methods. See their descriptions to learn more.\n *\n * By default, converter will {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consume} every value specified in\n * given `from...` query, i.e. `.from( { name: 'span', class: 'bold' } )` will make converter consume both `span` name\n * and `bold` class. It is possible to change this behavior using {@link ~ViewConverterBuilder#consuming consuming}\n * modifier. The modifier alters the last `fromXXX` query used before it. To learn more about consuming values,\n * see {@link module:engine/conversion/viewconsumable~ViewConsumable}.\n *\n * It is also possible to {@link module:engine/conversion/buildviewconverter~ViewConverterBuilder#withPriority change default priority}\n * of created converters to decide which converter should be fired earlier and which later. This is useful if you provide\n * a general converter but want to provide different converter for a specific-case (i.e. given view element is converted\n * always to given model element, but if it has given class it is converter to other model element). For this,\n * use {@link module:engine/conversion/buildviewconverter~ViewConverterBuilder#withPriority withPriority} modifier. The modifier alters\n * the last `from...` query used before it.\n *\n * Note that `to...` methods are \"terminators\", which means that should be the last one used in building converter.\n *\n * You can use {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder}\n * to create \"opposite\" converters - from model to view.\n */\nclass ViewConverterBuilder {\n\t/**\n\t * Creates `ViewConverterBuilder` with given `dispatchers` registered to it.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Dispatchers to which converters will be attached.\n\t\t *\n\t\t * @type {Array.<module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher>}\n\t\t * @private\n\t\t */\n\t\tthis._dispatchers = [];\n\n\t\t/**\n\t\t * Stores \"from\" queries.\n\t\t *\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._from = [];\n\t}\n\n\t/**\n\t * Set one or more dispatchers which the built converter will be attached to.\n\t *\n\t * @chainable\n\t * @param {...module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher} dispatchers One or more dispatchers.\n\t * @returns {module:engine/conversion/buildviewconverter~ViewConverterBuilder}\n\t */\n\tfor( ...dispatchers ) {\n\t\tthis._dispatchers = dispatchers;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Registers what view element should be converted.\n\t *\n\t *\t\tbuildViewConverter().for( dispatcher ).fromElement( 'p' ).toElement( 'paragraph' );\n\t *\n\t * @chainable\n\t * @param {String} elementName View element name.\n\t * @returns {module:engine/conversion/buildviewconverter~ViewConverterBuilder}\n\t */\n\tfromElement( elementName ) {\n\t\treturn this.from( { name: elementName } );\n\t}\n\n\t/**\n\t * Registers what view attribute should be converted.\n\t *\n\t *\t\tbuildViewConverter().for( dispatcher ).fromAttribute( 'style', { 'font-weight': 'bold' } ).toAttribute( 'bold', 'true' );\n\t *\n\t * @chainable\n\t * @param {String|RegExp} key View attribute key.\n\t * @param {String|RegExp} [value] View attribute value.\n\t * @returns {module:engine/conversion/buildviewconverter~ViewConverterBuilder}\n\t */\n\tfromAttribute( key, value = /.*/ ) {\n\t\tconst pattern = {};\n\n\t\tif ( key === 'style' || key === 'class' ) {\n\t\t\tpattern[ key ] = value;\n\t\t} else {\n\t\t\tpattern.attribute = {};\n\t\t\tpattern.attribute[ key ] = value;\n\t\t}\n\n\t\tconst matcher = new Matcher( pattern );\n\n\t\tthis._from.push( {\n\t\t\tmatcher,\n\t\t\tconsume: false,\n\t\t\tpriority: null,\n\t\t\tattributeKey: key\n\t\t} );\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Registers what view pattern should be converted. The method accepts either {@link module:engine/view/matcher~Matcher view matcher}\n\t * or view matcher pattern.\n\t *\n\t *\t\tconst matcher = new ViewMatcher();\n\t *\t\tmatcher.add( 'div', { class: 'quote' } );\n\t *\t\tbuildViewConverter().for( dispatcher ).from( matcher ).toElement( 'quote' );\n\t *\n\t *\t\tbuildViewConverter().for( dispatcher ).from( { name: 'span', class: 'bold' } ).toAttribute( 'bold', 'true' );\n\t *\n\t * @chainable\n\t * @param {Object|module:engine/view/matcher~Matcher} matcher View matcher or view matcher pattern.\n\t * @returns {module:engine/conversion/buildviewconverter~ViewConverterBuilder}\n\t */\n\tfrom( matcher ) {\n\t\tif ( !( matcher instanceof Matcher ) ) {\n\t\t\tmatcher = new Matcher( matcher );\n\t\t}\n\n\t\tthis._from.push( {\n\t\t\tmatcher,\n\t\t\tconsume: false,\n\t\t\tpriority: null\n\t\t} );\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Modifies which consumable values will be {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consumed}\n\t * by built converter.\n\t * It modifies the last `from...` query. Can be used after each `from...` query in given chain. Useful for providing\n\t * more specific matches.\n\t *\n\t *\t\t// This converter will only handle class bold conversion (to proper attribute) but span element\n\t *\t\t// conversion will have to be done in separate converter.\n\t *\t\t// Without consuming modifier, the converter would consume both class and name, so a converter for\n\t *\t\t// span element would not be fired.\n\t *\t\tbuildViewConverter().for( dispatcher )\n\t *\t\t\t.from( { name: 'span', class: 'bold' } ).consuming( { class: 'bold' } )\n\t *\t\t\t.toAttribute( 'bold', 'true' } );\n\t *\n\t *\t\tbuildViewConverter().for( dispatcher )\n\t *\t\t\t.fromElement( 'img' ).consuming( { name: true, attribute: [ 'src', 'title' ] } )\n\t *\t\t\t.toElement( ( viewElement ) => new ModelElement( 'image', { src: viewElement.getAttribute( 'src' ),\n\t *\t\t\t title: viewElement.getAttribute( 'title' ) } );\n\t *\n\t * **Note:** All and only values from passed object has to be consumable on converted view element. This means that\n\t * using `consuming` method, you can either make looser conversion conditions (like in first example) or tighter\n\t * conversion conditions (like in second example). So, the view element, to be converter, has to match query of\n\t * `from...` method and then have to have enough consumable values to consume.\n\t *\n\t * @see module:engine/conversion/viewconsumable~ViewConsumable\n\t * @chainable\n\t * @param {Object} consume Values to consume.\n\t * @returns {module:engine/conversion/buildviewconverter~ViewConverterBuilder}\n\t */\n\tconsuming( consume ) {\n\t\tconst lastFrom = this._from[ this._from.length - 1 ];\n\t\tlastFrom.consume = consume;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Changes default priority for built converter. It modifies the last `from...` query. Can be used after each\n\t * `from...` query in given chain. Useful for overwriting converters. The lower the number, the earlier converter will be fired.\n\t *\n\t *\t\tbuildViewConverter().for( dispatcher ).fromElement( 'p' ).toElement( 'paragraph' );\n\t *\t\t// Register converter with proper priority, otherwise \"p\" element would get consumed by first\n\t *\t\t// converter and the second converter would not be fired.\n\t *\t\tbuildViewConverter().for( dispatcher )\n\t *\t\t\t.from( { name: 'p', class: 'custom' } ).withPriority( 9 )\n\t *\t\t\t.toElement( 'customParagraph' );\n\t *\n\t * **Note:** `ViewConverterBuilder` takes care of applying all `toElement()` conversions before all `toAttribute()`\n\t * conversions. This is done by setting default `toElement()` priority to `normal` and `toAttribute()` priority to `low`.\n\t * It is recommended to set converter priority for `toElement()` around `0` (the value of `normal` priority)\n\t * and `toAttribute()` priority around `-1000` (the value of `low` priority).\n\t * It is important that model elements are created before attributes, otherwise attributes would\n\t * not be applied or other errors may occur.\n\t *\n\t * @chainable\n\t * @param {Number} priority Converter priority.\n\t * @returns {module:engine/conversion/buildviewconverter~ViewConverterBuilder}\n\t */\n\twithPriority( priority ) {\n\t\tconst lastFrom = this._from[ this._from.length - 1 ];\n\t\tlastFrom.priority = priority;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Registers what model element will be created by converter.\n\t *\n\t * Method accepts two ways of providing what kind of model element will be created. You can pass model element\n\t * name as a `string` or a function that will return model element instance. If you provide creator function,\n\t * it will be passed converted view element as first and only parameter.\n\t *\n\t *\t\tbuildViewConverter().for( dispatcher ).fromElement( 'p' ).toElement( 'paragraph' );\n\t *\t\tbuildViewConverter().for( dispatcher )\n\t *\t\t\t.fromElement( 'img' )\n\t *\t\t\t.toElement( ( viewElement ) => new ModelElement( 'image', { src: viewElement.getAttribute( 'src' ) } );\n\t *\n\t * @param {String|Function} element Model element name or model element creator function.\n\t */\n\ttoElement( element ) {\n\t\tfunction eventCallbackGen( from ) {\n\t\t\treturn ( evt, data, consumable, conversionApi ) => {\n\t\t\t\t// There is one callback for all patterns in the matcher.\n\t\t\t\t// This will be usually just one pattern but we support matchers with many patterns too.\n\t\t\t\tconst matchAll = from.matcher.matchAll( data.input );\n\n\t\t\t\t// If there is no match, this callback should not do anything.\n\t\t\t\tif ( !matchAll ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Now, for every match between matcher and actual element, we will try to consume the match.\n\t\t\t\tfor ( const match of matchAll ) {\n\t\t\t\t\t// Create model element basing on creator function or element name.\n\t\t\t\t\tconst modelElement = element instanceof Function ? element( data.input ) : new ModelElement( element );\n\n\t\t\t\t\t// Do not convert if element building function returned falsy value.\n\t\t\t\t\tif ( !modelElement ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check whether generated structure is okay with `Schema`.\n\t\t\t\t\tconst keys = Array.from( modelElement.getAttributeKeys() );\n\n\t\t\t\t\tif ( !conversionApi.schema.check( { name: modelElement.name, attributes: keys, inside: data.context } ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Try to consume appropriate values from consumable values list.\n\t\t\t\t\tif ( !consumable.consume( data.input, from.consume || match.match ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// If everything is fine, we are ready to start the conversion.\n\t\t\t\t\t// Add newly created `modelElement` to the parents stack.\n\t\t\t\t\tdata.context.push( modelElement );\n\n\t\t\t\t\t// Convert children of converted view element and append them to `modelElement`.\n\t\t\t\t\tconst modelChildren = conversionApi.convertChildren( data.input, consumable, data );\n\t\t\t\t\tconst insertPosition = ModelPosition.createAt( modelElement, 'end' );\n\t\t\t\t\tmodelWriter.insert( insertPosition, modelChildren );\n\n\t\t\t\t\t// Remove created `modelElement` from the parents stack.\n\t\t\t\t\tdata.context.pop();\n\n\t\t\t\t\t// Add `modelElement` as a result.\n\t\t\t\t\tdata.output = modelElement;\n\n\t\t\t\t\t// Prevent multiple conversion if there are other correct matches.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tthis._setCallback( eventCallbackGen, 'normal' );\n\t}\n\n\t/**\n\t * Registers what model attribute will be created by converter.\n\t *\n\t * Method accepts two ways of providing what kind of model attribute will be created. You can either pass two strings\n\t * representing attribute key and attribute value or a function that returns an object with `key` and `value` properties.\n\t * If you provide creator function, it will be passed converted view element as first and only parameter.\n\t *\n\t *\t\tbuildViewConverter().for( dispatcher ).fromAttribute( 'alt' ).toAttribute( 'alt' );\n\t *\t\tbuildViewConverter().for( dispatcher ).fromAttribute( 'style', { 'font-weight': 'bold' } ).toAttribute( 'bold', true );\n\t *\t\tbuildViewConverter().for( dispatcher )\n\t *\t\t\t.fromAttribute( 'class' )\n\t *\t\t\t.toAttribute( ( viewElement ) => ( { key: 'class', value: 'class-' + viewElement.getAttribute( 'class' ) } ) );\n\t *\n\t * @param {String|Function} keyOrCreator Attribute key or a creator function.\n\t * @param {String} [value] Attribute value. Ignored if `keyOrCreator` is not a `string`. If `keyOrCreator` is `string`,\n\t * if `value` is not set, attribute value from converted element will be used.\n\t */\n\ttoAttribute( keyOrCreator, value ) {\n\t\tfunction eventCallbackGen( from ) {\n\t\t\treturn ( evt, data, consumable, conversionApi ) => {\n\t\t\t\t// There is one callback for all patterns in the matcher.\n\t\t\t\t// This will be usually just one pattern but we support matchers with many patterns too.\n\t\t\t\tconst matchAll = from.matcher.matchAll( data.input );\n\n\t\t\t\t// If there is no match, this callback should not do anything.\n\t\t\t\tif ( !matchAll ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Now, for every match between matcher and actual element, we will try to consume the match.\n\t\t\t\tfor ( const match of matchAll ) {\n\t\t\t\t\t// Try to consume appropriate values from consumable values list.\n\t\t\t\t\tif ( !consumable.consume( data.input, from.consume || match.match ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Since we are converting to attribute we need an output on which we will set the attribute.\n\t\t\t\t\t// If the output is not created yet, we will create it.\n\t\t\t\t\tif ( !data.output ) {\n\t\t\t\t\t\tdata.output = conversionApi.convertChildren( data.input, consumable, data );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Use attribute creator function, if provided.\n\t\t\t\t\tlet attribute;\n\n\t\t\t\t\tif ( keyOrCreator instanceof Function ) {\n\t\t\t\t\t\tattribute = keyOrCreator( data.input );\n\n\t\t\t\t\t\tif ( !attribute ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tattribute = {\n\t\t\t\t\t\t\tkey: keyOrCreator,\n\t\t\t\t\t\t\tvalue: value ? value : data.input.getAttribute( from.attributeKey )\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set attribute on current `output`. `Schema` is checked inside this helper function.\n\t\t\t\t\tsetAttributeOn( data.output, attribute, data, conversionApi );\n\n\t\t\t\t\t// Prevent multiple conversion if there are other correct matches.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tthis._setCallback( eventCallbackGen, 'low' );\n\t}\n\n\t/**\n\t * Registers how model element marking marker range will be created by converter.\n\t *\n\t * Created element has to match the following pattern:\n\t *\n\t * \t\t{ name: '$marker', attribute: { data-name: /^\\w/ } }\n\t *\n\t * There are two ways of creating this element:\n\t *\n\t * 1. Makes sure that converted view element will have property `data-name` then converter will\n\t * automatically take this property value. In this case there is no need to provide creator function.\n\t * For the following view:\n\t *\n\t *\t\t<marker data-name=\"search\"></marker>foo<marker data-name=\"search\"></marker>\n\t *\n\t * converter should look like this:\n\t *\n\t *\t\tbuildViewConverter().for( dispatcher ).fromElement( 'marker' ).toMarker();\n\t *\n\t * 2. Creates element by creator:\n\t *\n\t * For the following view:\n\t *\n\t * \t\t<span foo=\"search\"></span>foo<span foo=\"search\"></span>\n\t *\n\t * converter should look like this:\n\t *\n\t * \t\tbuildViewConverter().for( dispatcher ).from( { name: 'span', { attribute: foo: /^\\w/ } } ).toMarker( ( data ) => {\n\t * \t\t\treturn new Element( '$marker', { 'data-name': data.getAttribute( 'foo' ) } );\n\t * \t\t} );\n\t *\n\t * @param {Function} [creator] Creator function.\n\t */\n\ttoMarker( creator ) {\n\t\tfunction eventCallbackGen( from ) {\n\t\t\treturn ( evt, data, consumable ) => {\n\t\t\t\t// There is one callback for all patterns in the matcher.\n\t\t\t\t// This will be usually just one pattern but we support matchers with many patterns too.\n\t\t\t\tconst matchAll = from.matcher.matchAll( data.input );\n\n\t\t\t\t// If there is no match, this callback should not do anything.\n\t\t\t\tif ( !matchAll ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet modelElement;\n\n\t\t\t\t// When creator is provided then create model element basing on creator function.\n\t\t\t\tif ( creator instanceof Function ) {\n\t\t\t\t\tmodelElement = creator( data.input );\n\t\t\t\t// When there is no creator then create model element basing on data from view element.\n\t\t\t\t} else {\n\t\t\t\t\tmodelElement = new ModelElement( '$marker', { 'data-name': data.input.getAttribute( 'data-name' ) } );\n\t\t\t\t}\n\n\t\t\t\t// Check if model element is correct (has proper name and property).\n\t\t\t\tif ( modelElement.name != '$marker' || typeof modelElement.getAttribute( 'data-name' ) != 'string' ) {\n\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t'build-view-converter-invalid-marker: Invalid model element to mark marker range.'\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Now, for every match between matcher and actual element, we will try to consume the match.\n\t\t\t\tfor ( const match of matchAll ) {\n\t\t\t\t\t// Try to consume appropriate values from consumable values list.\n\t\t\t\t\tif ( !consumable.consume( data.input, from.consume || match.match ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tdata.output = modelElement;\n\n\t\t\t\t\t// Prevent multiple conversion if there are other correct matches.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tthis._setCallback( eventCallbackGen, 'normal' );\n\t}\n\n\t/**\n\t * Helper function that uses given callback generator to created callback function and sets it on registered dispatchers.\n\t *\n\t * @param eventCallbackGen\n\t * @param defaultPriority\n\t * @private\n\t */\n\t_setCallback( eventCallbackGen, defaultPriority ) {\n\t\t// We will add separate event callback for each registered `from` entry.\n\t\tfor ( const from of this._from ) {\n\t\t\t// We have to figure out event name basing on matcher's patterns.\n\t\t\t// If there is exactly one pattern and it has `name` property we will used that name.\n\t\t\tconst matcherElementName = from.matcher.getElementName();\n\t\t\tconst eventName = matcherElementName ? 'element:' + matcherElementName : 'element';\n\t\t\tconst eventCallback = eventCallbackGen( from );\n\n\t\t\tconst priority = from.priority === null ? defaultPriority : from.priority;\n\n\t\t\t// Add event to each registered dispatcher.\n\t\t\tfor ( const dispatcher of this._dispatchers ) {\n\t\t\t\tdispatcher.on( eventName, eventCallback, { priority } );\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Helper function that sets given attributes on given `module:engine/model/node~Node` or\n// `module:engine/model/documentfragment~DocumentFragment`.\nfunction setAttributeOn( toChange, attribute, data, conversionApi ) {\n\tif ( isIterable( toChange ) ) {\n\t\tfor ( const node of toChange ) {\n\t\t\tsetAttributeOn( node, attribute, data, conversionApi );\n\t\t}\n\n\t\treturn;\n\t}\n\n\tconst keys = Array.from( toChange.getAttributeKeys() );\n\tkeys.push( attribute.key );\n\n\tconst schemaQuery = {\n\t\tname: toChange.name || '$text',\n\t\tattributes: keys,\n\t\tinside: data.context\n\t};\n\n\tif ( conversionApi.schema.check( schemaQuery ) ) {\n\t\ttoChange.setAttribute( attribute.key, attribute.value );\n\t}\n}\n\n/**\n * Entry point for view-to-model converters builder. This chainable API makes it easy to create basic, most common\n * view-to-model converters and attach them to provided dispatchers. The method returns an instance of\n * {@link module:engine/conversion/buildviewconverter~ViewConverterBuilder}.\n */\nexport default function buildViewConverter() {\n\treturn new ViewConverterBuilder();\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/buildviewconverter.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/attributecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\n/**\n * An extension of the base {@link module:core/command~Command} class, which provides utilities for a command\n * that toggles a single attribute on a text or an element.\n *\n * `AttributeCommand` uses {@link module:engine/model/document~Document#selection}\n * to decide which nodes (if any) should be changed, and applies or removes the attribute from them.\n *\n * The command checks the {@link module:engine/model/document~Document#schema} to decide if it can be enabled\n * for the current selection and to which nodes the attribute can be applied.\n *\n * @extends module:core/command~Command\n */\nexport default class AttributeCommand extends Command {\n\t/**\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {String} attributeKey Attribute that will be set by the command.\n\t */\n\tconstructor( editor, attributeKey ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The attribute that will be set by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.attributeKey = attributeKey;\n\n\t\t/**\n\t\t * Flag indicating whether the command is active. The command is active when the\n\t\t * {@link module:engine/model/selection~Selection#hasAttribute selection has the attribute} which means that:\n\t\t *\n\t\t * * If the selection is not empty &ndash; That it starts in a text (or another node) which has the attribute set.\n\t\t * * If the selection is empty &ndash; That the selection has the attribute itself (which means that newly typed\n\t\t * text will have this attribute, too).\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t}\n\n\t/**\n\t * Updates the command's {@link #value} and {@link #isEnabled} based on the current selection.\n\t */\n\trefresh() {\n\t\tconst doc = this.editor.document;\n\n\t\tthis.value = doc.selection.hasAttribute( this.attributeKey );\n\t\tthis.isEnabled = doc.schema.checkAttributeInSelection( doc.selection, this.attributeKey );\n\t}\n\n\t/**\n\t * Executes the command &mdash; applies the attribute to the selection or removes it from the selection.\n\t *\n\t * If the command is active (`value == true`), it will remove attributes. Otherwise, it will set attributes.\n\t *\n\t * The execution result differs, depending on the {@link module:engine/model/document~Document#selection}:\n\t *\n\t * * If the selection is on a range, the command applies the attribute to all nodes in that range\n\t * (if they are allowed to have this attribute by the {@link module:engine/model/schema~Schema schema}).\n\t * * If the selection is collapsed in a non-empty node, the command applies the attribute to the\n\t * {@link module:engine/model/document~Document#selection} itself (note that typed characters copy attributes from the selection).\n\t * * If the selection is collapsed in an empty node, the command applies the attribute to the parent node of the selection (note\n\t * that the selection inherits all attributes from a node if it is in an empty node).\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Command options.\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will apply the attribute,\n\t * otherwise the command will remove the attribute.\n\t * If not set, the command will look for its current value to decide what it should do.\n\t * @param {module:engine/model/batch~Batch} [options.batch] A batch to group undo steps.\n\t */\n\texecute( options = {} ) {\n\t\tconst doc = this.editor.document;\n\t\tconst selection = doc.selection;\n\t\tconst value = ( options.forceValue === undefined ) ? !this.value : options.forceValue;\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tif ( value ) {\n\t\t\t\t\tselection.setAttribute( this.attributeKey, true );\n\t\t\t\t} else {\n\t\t\t\t\tselection.removeAttribute( this.attributeKey );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst ranges = doc.schema.getValidRanges( selection.getRanges(), this.attributeKey );\n\t\t\t\tconst batch = options.batch || doc.batch();\n\n\t\t\t\tfor ( const range of ranges ) {\n\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\tbatch.setAttribute( range, this.attributeKey, value );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbatch.removeAttribute( range, this.attributeKey );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-basic-styles/src/attributecommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module block-quote/blockquotecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\nimport Position from '@ckeditor/ckeditor5-engine/src/model/position';\nimport Element from '@ckeditor/ckeditor5-engine/src/model/element';\nimport Range from '@ckeditor/ckeditor5-engine/src/model/range';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The block quote command plugin.\n *\n * @extends module:core/command~Command\n */\nexport default class BlockQuoteCommand extends Command {\n\t/**\n\t * Whether the selection starts in a block quote.\n\t *\n\t * @observable\n\t * @readonly\n\t * @member {Boolean} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command. When the command {@link #value is on}, all block quotes within\n\t * the selection will be removed. If it is off, all selected blocks will be wrapped with\n\t * a block quote.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Options for executed command.\n\t * @param {module:engine/model/batch~Batch} [options.batch] Batch to collect all the change steps.\n\t * A new batch will be created if this option is not set.\n\t */\n\texecute( options = {} ) {\n\t\tconst doc = this.editor.document;\n\t\tconst schema = doc.schema;\n\t\tconst batch = options.batch || doc.batch();\n\t\tconst blocks = Array.from( doc.selection.getSelectedBlocks() );\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tif ( this.value ) {\n\t\t\t\tthis._removeQuote( batch, blocks.filter( findQuote ) );\n\t\t\t} else {\n\t\t\t\tconst blocksToQuote = blocks.filter( block => {\n\t\t\t\t\t// Already quoted blocks needs to be considered while quoting too\n\t\t\t\t\t// in order to reuse their <bQ> elements.\n\t\t\t\t\treturn findQuote( block ) || checkCanBeQuoted( schema, block );\n\t\t\t\t} );\n\n\t\t\t\tthis._applyQuote( batch, blocksToQuote );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\tconst firstBlock = first( this.editor.document.selection.getSelectedBlocks() );\n\n\t\t// In the current implementation, the block quote must be an immediate parent of a block element.\n\t\treturn !!( firstBlock && findQuote( firstBlock ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.document.selection;\n\t\tconst schema = this.editor.document.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn checkCanBeQuoted( schema, firstBlock );\n\t}\n\n\t/**\n\t * Removes the quote from given blocks.\n\t *\n\t * If blocks which are supposed to be \"unquoted\" are in the middle of a quote,\n\t * start it or end it, then the quote will be split (if needed) and the blocks\n\t * will be moved out of it, so other quoted blocks remained quoted.\n\t *\n\t * @private\n\t * @param {module:engine/model/batch~Batch} batch\n\t * @param {Array.<module:engine/model/element~Element>} blocks\n\t */\n\t_removeQuote( batch, blocks ) {\n\t\t// Unquote all groups of block. Iterate in the reverse order to not break following ranges.\n\t\tgetRangesOfBlockGroups( blocks ).reverse().forEach( groupRange => {\n\t\t\tif ( groupRange.start.isAtStart && groupRange.end.isAtEnd ) {\n\t\t\t\tbatch.unwrap( groupRange.start.parent );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>).\n\t\t\tif ( groupRange.start.isAtStart ) {\n\t\t\t\tconst positionBefore = Position.createBefore( groupRange.start.parent );\n\n\t\t\t\tbatch.move( groupRange, positionBefore );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block\n\t\t\t// so we move the items there.\n\t\t\tif ( !groupRange.end.isAtEnd ) {\n\t\t\t\tbatch.split( groupRange.end );\n\t\t\t}\n\n\t\t\t// Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.\n\n\t\t\tconst positionAfter = Position.createAfter( groupRange.end.parent );\n\n\t\t\tbatch.move( groupRange, positionAfter );\n\t\t} );\n\t}\n\n\t/**\n\t * Applies the quote to given blocks.\n\t *\n\t * @private\n\t * @param {module:engine/model/batch~Batch} batch\n\t * @param {Array.<module:engine/model/element~Element>} blocks\n\t */\n\t_applyQuote( batch, blocks ) {\n\t\tconst quotesToMerge = [];\n\n\t\t// Quote all groups of block. Iterate in the reverse order to not break following ranges.\n\t\tgetRangesOfBlockGroups( blocks ).reverse().forEach( groupRange => {\n\t\t\tlet quote = findQuote( groupRange.start );\n\n\t\t\tif ( !quote ) {\n\t\t\t\tquote = new Element( 'blockQuote' );\n\n\t\t\t\tbatch.wrap( groupRange, quote );\n\t\t\t}\n\n\t\t\tquotesToMerge.push( quote );\n\t\t} );\n\n\t\t// Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through\n\t\t// the <bQ> elements in the source order (due to how merge works it moves the right element's content\n\t\t// to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements\n\t\t// we want to keep the reference to the first (furthest left) one.\n\t\tquotesToMerge.reverse().reduce( ( currentQuote, nextQuote ) => {\n\t\t\tif ( currentQuote.nextSibling == nextQuote ) {\n\t\t\t\tbatch.merge( Position.createAfter( currentQuote ) );\n\n\t\t\t\treturn currentQuote;\n\t\t\t}\n\n\t\t\treturn nextQuote;\n\t\t} );\n\t}\n}\n\nfunction findQuote( elementOrPosition ) {\n\treturn elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null;\n}\n\n// Returns a minimal array of ranges containing groups of subsequent blocks.\n//\n// content: abcdefgh\n// blocks: [ a, b, d , f, g, h ]\n// output ranges: [ab]c[d]e[fgh]\n//\n// @param {Array.<module:engine/model/element~Element>} blocks\n// @returns {Array.<module:engine/model/range~Range>}\nfunction getRangesOfBlockGroups( blocks ) {\n\tlet startPosition;\n\tlet i = 0;\n\tconst ranges = [];\n\n\twhile ( i < blocks.length ) {\n\t\tconst block = blocks[ i ];\n\t\tconst nextBlock = blocks[ i + 1 ];\n\n\t\tif ( !startPosition ) {\n\t\t\tstartPosition = Position.createBefore( block );\n\t\t}\n\n\t\tif ( !nextBlock || block.nextSibling != nextBlock ) {\n\t\t\tranges.push( new Range( startPosition, Position.createAfter( block ) ) );\n\t\t\tstartPosition = null;\n\t\t}\n\n\t\ti++;\n\t}\n\n\treturn ranges;\n}\n\n// Checks whether <bQ> can wrap the block.\nfunction checkCanBeQuoted( schema, block ) {\n\tconst isBQAllowed = schema.check( {\n\t\tname: 'blockQuote',\n\t\tinside: Position.createBefore( block )\n\t} );\n\tconst isBlockAllowedInBQ = schema.check( {\n\t\tname: block.name,\n\t\tattributes: Array.from( block.getAttributeKeys() ),\n\t\tinside: 'blockQuote'\n\t} );\n\n\treturn isBQAllowed && isBlockAllowedInBQ;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-block-quote/src/blockquotecommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module block-quote/blockquoteengine\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport BlockQuoteCommand from './blockquotecommand';\n\nimport buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';\nimport buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';\n\n/**\n * The block quote engine.\n *\n * Introduces the `'blockQuote'` command and the `'blockQuote'` model element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuoteEngine extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.document.schema;\n\n\t\teditor.commands.add( 'blockQuote', new BlockQuoteCommand( editor ) );\n\n\t\tschema.registerItem( 'blockQuote' );\n\t\tschema.allow( { name: 'blockQuote', inside: '$root' } );\n\t\tschema.allow( { name: '$block', inside: 'blockQuote' } );\n\n\t\tbuildViewConverter().for( editor.data.viewToModel )\n\t\t\t.fromElement( 'blockquote' )\n\t\t\t.toElement( 'blockQuote' );\n\n\t\tbuildModelConverter().for( editor.data.modelToView, editor.editing.modelToView )\n\t\t\t.fromElement( 'blockQuote' )\n\t\t\t.toElement( 'blockquote' );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst schema = this.editor.document.schema;\n\n\t\t// TODO\n\t\t// Workaround for https://github.com/ckeditor/ckeditor5-engine/issues/532#issuecomment-280924650.\n\t\tif ( schema.hasItem( 'listItem' ) ) {\n\t\t\tschema.allow( {\n\t\t\t\tname: 'listItem',\n\t\t\t\tinside: 'blockQuote',\n\t\t\t\tattributes: [ 'type', 'indent' ]\n\t\t\t} );\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-block-quote/src/blockquoteengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* eslint-env browser */\n\n'use strict';\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\n\nconst BASE64_HEADER_REG_EXP = /^data:(\\S*?);base64,/;\n\n/**\n * FileUploader class used to upload single file.\n */\nclass FileUploader {\n\t/**\n\t * Creates `FileUploader` instance.\n\t *\n\t * @param {Blob|String} fileOrData A blob object or a data string encoded with Base64.\n\t * @param {Token} token Token used for authentication.\n\t * @param {String} apiAddress API address.\n\t */\n\tconstructor( fileOrData, token, apiAddress ) {\n\t\tif ( !fileOrData ) {\n\t\t\tthrow new Error( 'File must be provided' );\n\t\t}\n\n\t\tif ( !token ) {\n\t\t\tthrow new Error( 'Token must be provided' );\n\t\t}\n\n\t\tif ( !apiAddress ) {\n\t\t\tthrow new Error( 'Api address must be provided' );\n\t\t}\n\n\t\t/**\n\t\t * A file that is being uploaded.\n\t\t *\n\t\t * @type {Blob}\n\t\t */\n\t\tthis.file = _isBase64( fileOrData ) ? _base64ToBlob( fileOrData ) : fileOrData;\n\n\t\t/**\n\t\t * CKEditor Cloud Services access token.\n\t\t *\n\t\t * @type {Token}\n\t\t * @private\n\t\t */\n\t\tthis._token = token;\n\n\t\t/**\n\t\t * CKEditor Cloud Services API address.\n\t\t *\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._apiAddress = apiAddress;\n\t}\n\n\t/**\n\t * Registers callback on `progress` event.\n\t *\n\t * @chainable\n\t * @param {Function} callback\n\t * @returns {FileUploader}\n\t */\n\tonProgress( callback ) {\n\t\tthis.on( 'progress', ( event, data ) => callback( data ) );\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Registers callback on `error` event. Event is called once when error occurs.\n\t *\n\t * @chainable\n\t * @param {Function} callback\n\t * @returns {FileUploader}\n\t */\n\tonError( callback ) {\n\t\tthis.once( 'error', ( event, data ) => callback( data ) );\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Aborts upload process.\n\t */\n\tabort() {\n\t\tthis.xhr.abort();\n\t}\n\n\t/**\n\t * Sends XHR request to API.\n\t *\n\t * @chainable\n\t * @returns {Promise.<Object>}\n\t */\n\tsend() {\n\t\tthis._prepareRequest();\n\t\tthis._attachXHRListeners();\n\n\t\treturn this._sendRequest();\n\t}\n\n\t/**\n\t * Prepares XHR request.\n\t *\n\t * @private\n\t */\n\t_prepareRequest() {\n\t\tconst xhr = new XMLHttpRequest();\n\n\t\txhr.open( 'POST', this._apiAddress );\n\t\txhr.setRequestHeader( 'Authorization', this._token.value );\n\t\txhr.responseType = 'json';\n\n\t\tthis.xhr = xhr;\n\t}\n\n\t/**\n\t * Attaches listeners to the XHR.\n\t *\n\t * @private\n\t */\n\t_attachXHRListeners() {\n\t\tconst that = this;\n\t\tconst xhr = this.xhr;\n\n\t\txhr.addEventListener( 'error', onError( 'Network Error' ) );\n\t\txhr.addEventListener( 'abort', onError( 'Abort' ) );\n\n\t\t/* istanbul ignore else */\n\t\tif ( xhr.upload ) {\n\t\t\txhr.upload.addEventListener( 'progress', event => {\n\t\t\t\tif ( event.lengthComputable ) {\n\t\t\t\t\tthis.fire( 'progress', {\n\t\t\t\t\t\ttotal: event.total,\n\t\t\t\t\t\tuploaded: event.loaded\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\txhr.addEventListener( 'load', () => {\n\t\t\tconst statusCode = xhr.status;\n\t\t\tconst xhrResponse = xhr.response;\n\n\t\t\tif ( statusCode < 200 || statusCode > 299 ) {\n\t\t\t\treturn this.fire( 'error', xhrResponse.message || xhrResponse.error );\n\t\t\t}\n\t\t} );\n\n\t\tfunction onError( message ) {\n\t\t\treturn () => that.fire( 'error', message );\n\t\t}\n\t}\n\n\t/**\n\t * Sends XHR request.\n\t *\n\t * @private\n\t */\n\t_sendRequest() {\n\t\tconst formData = new FormData();\n\t\tconst xhr = this.xhr;\n\n\t\tformData.append( 'file', this.file );\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\txhr.addEventListener( 'load', () => {\n\t\t\t\tconst statusCode = xhr.status;\n\t\t\t\tconst xhrResponse = xhr.response;\n\n\t\t\t\tif ( statusCode < 200 || statusCode > 299 ) {\n\t\t\t\t\treturn reject( xhrResponse.message || xhrResponse.error );\n\t\t\t\t}\n\n\t\t\t\treturn resolve( xhrResponse );\n\t\t\t} );\n\n\t\t\txhr.addEventListener( 'error', () => reject( 'Network Error' ) );\n\t\t\txhr.addEventListener( 'abort', () => reject( 'Abort' ) );\n\n\t\t\txhr.send( formData );\n\t\t} );\n\t}\n\n\t/**\n\t * Fired when error occurs.\n\t *\n\t * @event error\n\t * @param {String} error Error message\n\t */\n\n\t/**\n\t * Fired on upload progress.\n\t *\n\t * @event progress\n\t * @param {Object} status Total and uploaded status\n\t */\n}\n\nmix( FileUploader, EmitterMixin );\n\n/**\n * Transforms Base64 string data into file.\n *\n * @param {String} base64 String data.\n * @param {Number} [sliceSize=512]\n * @returns {Blob}\n * @private\n */\nfunction _base64ToBlob( base64, sliceSize = 512 ) {\n\ttry {\n\t\tconst contentType = base64.match( BASE64_HEADER_REG_EXP )[ 1 ];\n\t\tconst base64Data = atob( base64.replace( BASE64_HEADER_REG_EXP, '' ) );\n\n\t\tconst byteArrays = [];\n\n\t\tfor ( let offset = 0; offset < base64Data.length; offset += sliceSize ) {\n\t\t\tconst slice = base64Data.slice( offset, offset + sliceSize );\n\t\t\tconst byteNumbers = new Array( slice.length );\n\n\t\t\tfor ( let i = 0; i < slice.length; i++ ) {\n\t\t\t\tbyteNumbers[ i ] = slice.charCodeAt( i );\n\t\t\t}\n\n\t\t\tbyteArrays.push( new Uint8Array( byteNumbers ) );\n\t\t}\n\n\t\treturn new Blob( byteArrays, { type: contentType } );\n\t} catch ( error ) {\n\t\tthrow new Error( 'Problem with decoding Base64 image data.' );\n\t}\n}\n\n/**\n * Checks that string is Base64.\n *\n * @param {String} string\n * @returns {Boolean}\n * @private\n */\nfunction _isBase64( string ) {\n\tif ( typeof string !== 'string' ) {\n\t\treturn false;\n\t}\n\n\tconst match = string.match( BASE64_HEADER_REG_EXP );\n\treturn !!( match && match.length );\n}\n\nexport default FileUploader;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/@ckeditor/ckeditor-cloudservices-core/src/uploadgateway/fileuploader.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n'use strict';\n\nimport FileUploader from './fileuploader';\n\n/**\n * UploadGateway abstracts file uploads to CKEditor Cloud Services.\n */\nexport default class UploadGateway {\n\t/**\n\t * Creates `UploadGateway` instance.\n\t *\n\t * @param {Token} token Token used for authentication.\n\t * @param {String} apiAddress API address.\n\t */\n\tconstructor( token, apiAddress ) {\n\t\tif ( !token ) {\n\t\t\tthrow new Error( 'Token must be provided' );\n\t\t}\n\n\t\tif ( !apiAddress ) {\n\t\t\tthrow new Error( 'Api address must be provided' );\n\t\t}\n\n\t\t/**\n\t\t * CKEditor Cloud Services access token.\n\t\t *\n\t\t * @type {Token}\n\t\t * @private\n\t\t */\n\t\tthis._token = token;\n\n\t\t/**\n\t\t * CKEditor Cloud Services API address.\n\t\t *\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._apiAddress = apiAddress;\n\t}\n\n\t/**\n\t * Creates a {@link FileUploader} instance that wraps file upload process.\n\t * The file is being sent at a time when the method {@link FileUploader#then then} is called\n\t * or when {@link FileUploader#send send} method is called.\n\t *\n\t * const token = await Token.create( 'https://token-endpoint' );\n\t * new UploadGateway( token, 'https://example.org' )\n\t * .upload( 'FILE' )\n\t * .onProgress( ( data ) => console.log( data ) )\n\t * .send()\n\t * .then( ( response ) => console.log( response ) );\n\t *\n\t * // OR\n\t *\n\t * const token = await Token.create( 'https://token-endpoint' );\n\t * new UploadGateway( token, 'https://example.org' )\n\t * .upload( 'FILE' )\n\t * .onProgress( ( data ) => console.log( data ) )\n\t * .send()\n\t * .then( ( response ) => console.log( response ) );\n\t *\n\t * @param {Blob/String} fileOrData A blob object or a data string encoded with Base64.\n\t * @returns {FileUploader} Returns `FileUploader` instance.\n\t */\n\tupload( fileOrData ) {\n\t\treturn new FileUploader( fileOrData, this._token, this._apiAddress );\n\t}\n}\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/@ckeditor/ckeditor-cloudservices-core/src/uploadgateway/uploadgateway.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image/converters\n */\n\nimport ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';\nimport ModelDocumentFragment from '@ckeditor/ckeditor5-engine/src/model/documentfragment';\nimport modelWriter from '@ckeditor/ckeditor5-engine/src/model/writer';\n\n/**\n * Returns a function that converts the image view representation:\n *\n *\t\t<figure class=\"image\"><img src=\"...\" alt=\"...\"></img></figure>\n *\n * to the model representation:\n *\n *\t\t<image src=\"...\" alt=\"...\"></image>\n *\n * The entire content of the `<figure>` element except the first `<img>` is being converted as children\n * of the `<image>` model element.\n *\n * @returns {Function}\n */\nexport function viewFigureToModel() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\t// Do not convert if this is not an \"image figure\".\n\t\tif ( !consumable.test( data.input, { name: true, class: 'image' } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not convert if image cannot be placed in model at this context.\n\t\tif ( !conversionApi.schema.check( { name: 'image', inside: data.context, attributes: 'src' } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Find an image element inside the figure element.\n\t\tconst viewImage = Array.from( data.input.getChildren() ).find( viewChild => viewChild.is( 'img' ) );\n\n\t\t// Do not convert if image element is absent, is missing src attribute or was already converted.\n\t\tif ( !viewImage || !viewImage.hasAttribute( 'src' ) || !consumable.test( viewImage, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert view image to model image.\n\t\tconst modelImage = conversionApi.convertItem( viewImage, consumable, data );\n\n\t\t// Convert rest of figure element's children, but in the context of model image, because those converted\n\t\t// children will be added as model image children.\n\t\tdata.context.push( modelImage );\n\n\t\tconst modelChildren = conversionApi.convertChildren( data.input, consumable, data );\n\n\t\tdata.context.pop();\n\n\t\t// Add converted children to model image.\n\t\tmodelWriter.insert( ModelPosition.createAt( modelImage ), modelChildren );\n\n\t\t// Set model image as conversion result.\n\t\tdata.output = modelImage;\n\t};\n}\n\n/**\n * Creates the image attribute converter for provided model conversion dispatchers.\n *\n * @param {Array.<module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher>} dispatchers\n * @param {String} attributeName\n * @param {Function} [converter] Custom converter for the attribute - default one converts attribute from model `image` element\n * to the same attribute in `img` in the view.\n */\nexport function createImageAttributeConverter( dispatchers, attributeName, converter = modelToViewAttributeConverter ) {\n\tfor ( const dispatcher of dispatchers ) {\n\t\tdispatcher.on( `addAttribute:${ attributeName }:image`, converter() );\n\t\tdispatcher.on( `changeAttribute:${ attributeName }:image`, converter() );\n\t\tdispatcher.on( `removeAttribute:${ attributeName }:image`, converter() );\n\t}\n}\n\n/**\n * Converter used to convert `srcset` model image's attribute to `srcset`, `sizes` and `width` attributes in the view.\n *\n * @return {Function}\n */\nexport function srcsetAttributeConverter() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst parts = evt.name.split( ':' );\n\t\tconst consumableType = parts[ 0 ] + ':' + parts[ 1 ];\n\t\tconst modelImage = data.item;\n\n\t\tif ( !consumable.consume( modelImage, consumableType ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst figure = conversionApi.mapper.toViewElement( modelImage );\n\t\tconst img = figure.getChild( 0 );\n\t\tconst type = parts[ 0 ];\n\n\t\tif ( type == 'removeAttribute' ) {\n\t\t\tconst srcset = data.attributeOldValue;\n\n\t\t\tif ( srcset.data ) {\n\t\t\t\timg.removeAttribute( 'srcset' );\n\t\t\t\timg.removeAttribute( 'sizes' );\n\n\t\t\t\tif ( srcset.width ) {\n\t\t\t\t\timg.removeAttribute( 'width' );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst srcset = data.attributeNewValue;\n\n\t\t\tif ( srcset.data ) {\n\t\t\t\timg.setAttribute( 'srcset', srcset.data );\n\t\t\t\t// Always outputting `100vw`. See https://github.com/ckeditor/ckeditor5-image/issues/2.\n\t\t\t\timg.setAttribute( 'sizes', '100vw' );\n\n\t\t\t\tif ( srcset.width ) {\n\t\t\t\t\timg.setAttribute( 'width', srcset.width );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Returns model to view image converter converting given attribute, and adding it to `img` element nested inside `figure` element.\n//\n// @private\nfunction modelToViewAttributeConverter() {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst parts = evt.name.split( ':' );\n\t\tconst consumableType = parts[ 0 ] + ':' + parts[ 1 ];\n\t\tconst modelImage = data.item;\n\n\t\tif ( !consumable.consume( modelImage, consumableType ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst figure = conversionApi.mapper.toViewElement( modelImage );\n\t\tconst img = figure.getChild( 0 );\n\t\tconst type = parts[ 0 ];\n\n\t\tif ( type == 'removeAttribute' ) {\n\t\t\timg.removeAttribute( data.attributeKey );\n\t\t} else {\n\t\t\timg.setAttribute( data.attributeKey, data.attributeNewValue );\n\t\t}\n\t};\n}\n\n// Holds all images that were converted for autohoisting.\nconst autohoistedImages = new WeakSet();\n\n/**\n * A converter which converts `<img>` {@link module:engine/view/element~Element view elements} that can be hoisted.\n *\n * If an `<img>` view element has not been converted, this converter checks if that element could be converted in any\n * context \"above\". If it could, the converter converts the `<img>` element even though it is not allowed in the current\n * context and marks it to be autohoisted. Then {@link module:image/image/converters~hoistImageThroughElement another converter}\n * moves the converted element to the correct location.\n */\nexport function convertHoistableImage( evt, data, consumable, conversionApi ) {\n\tconst img = data.input;\n\n\t// If the image has not been consumed (converted)...\n\tif ( !consumable.test( img, { name: true, attribute: [ 'src' ] } ) ) {\n\t\treturn;\n\t}\n\t// At this point the image has not been converted because it was not allowed by schema. It might be in wrong\n\t// context or missing an attribute, but above we already checked whether the image has mandatory src attribute.\n\n\t// If the image would be allowed if it was in one of its ancestors...\n\tconst allowedContext = _findAllowedContext( { name: 'image', attributes: [ 'src' ] }, data.context, conversionApi.schema );\n\n\tif ( !allowedContext ) {\n\t\treturn;\n\t}\n\n\t// Convert it in that context...\n\tconst newData = Object.assign( {}, data );\n\tnewData.context = allowedContext;\n\n\tdata.output = conversionApi.convertItem( img, consumable, newData );\n\n\t// And mark that image to be hoisted.\n\tautohoistedImages.add( data.output );\n}\n\n// Basing on passed `context`, searches for \"closest\" context in which model element represented by `modelData`\n// would be allowed by `schema`.\n//\n// @private\n// @param {Object} modelData Object describing model element to check. Has two properties: `name` with model element name\n// and `attributes` with keys of attributes of that model element.\n// @param {Array} context Context in which original conversion was supposed to take place.\n// @param {module:engine/model/schema~Schema} schema Schema to check with.\n// @returns {Array|null} Context in which described model element would be allowed by `schema` or `null` if such context\n// could not been found.\nfunction _findAllowedContext( modelData, context, schema ) {\n\t// Copy context array so we won't modify original array.\n\tcontext = context.slice();\n\n\t// Prepare schema query to check with schema.\n\t// Since `inside` property is passed as reference to `context` variable, we don't need to modify `schemaQuery`.\n\tconst schemaQuery = {\n\t\tname: modelData.name,\n\t\tattributes: modelData.attributes,\n\t\tinside: context\n\t};\n\n\t// Try out all possible contexts.\n\twhile ( context.length && !schema.check( schemaQuery ) ) {\n\t\tconst parent = context.pop();\n\t\tconst parentName = typeof parent === 'string' ? parent : parent.name;\n\n\t\t// Do not try to autohoist \"above\" limiting element.\n\t\tif ( schema.limits.has( parentName ) ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// If `context` has any items it means that image is allowed in that context. Return that context.\n\t// If `context` has no items it means that image was not allowed in any of possible contexts. Return `null`.\n\treturn context.length ? context : null;\n}\n\n/**\n * A converter which hoists `<image>` {@link module:engine/model/element~Element model elements} to allowed context.\n *\n * It looks through all children of the converted {@link module:engine/view/element~Element view element} if it\n * was converted to a model element. It breaks the model element if an `<image>` to-be-hoisted is found.\n *\n *\t\t<div><paragraph>x<image src=\"foo.jpg\"></image>x</paragraph></div> ->\n *\t\t<div><paragraph>x</paragraph></div><image src=\"foo.jpg\"></image><div><paragraph>x</paragraph></div>\n *\n * This works deeply, as shown in the example. This converter added for the `<paragraph>` element will break the `<paragraph>`\n * element and pass the {@link module:engine/model/documentfragment~DocumentFragment document fragment} in `data.output`.\n * Then, the `<div>` will be handled by this converter and will be once again broken to hoist the `<image>` up to the root.\n *\n * **Note:** This converter should be executed only after the view element has already been converted, which means that\n * `data.output` for that view element should be already generated when this converter is fired.\n */\nexport function hoistImageThroughElement( evt, data ) {\n\t// If this element has been properly converted...\n\tif ( !data.output ) {\n\t\treturn;\n\t}\n\n\t// And it is an element...\n\t// (If it is document fragment autohoisting does not have to break anything anyway.)\n\t// (And if it is text there are no children here.)\n\tif ( !data.output.is( 'element' ) ) {\n\t\treturn;\n\t}\n\n\t// This will hold newly generated output. At the beginning it is only the original element.\n\tconst newOutput = [];\n\n\t// Check if any of its children is to be hoisted...\n\t// Start from the last child - it is easier to break that way.\n\tfor ( let i = data.output.childCount - 1; i >= 0; i-- ) {\n\t\tconst child = data.output.getChild( i );\n\n\t\tif ( autohoistedImages.has( child ) ) {\n\t\t\t// Break autohoisted element's parent:\n\t\t\t// <parent>{ left-children... }<authoistedElement />{ right-children... }</parent> --->\n\t\t\t// <parent>{ left-children... }</parent><autohoistedElement /><parent>{ right-children... }</parent>\n\t\t\t//\n\t\t\t// or\n\t\t\t//\n\t\t\t// <parent>{ left-children... }<autohoistedElement /></parent> --->\n\t\t\t// <parent>{ left-children... }</parent><autohoistedElement />\n\t\t\t//\n\t\t\t// or\n\t\t\t//\n\t\t\t// <parent><autohoistedElement />{ right-children... }</parent> --->\n\t\t\t// <autohoistedElement /><parent>{ right-children... }</parent>\n\t\t\t//\n\t\t\t// or\n\t\t\t//\n\t\t\t// <parent><autohoistedElement /></parent> ---> <autohoistedElement />\n\n\t\t\t// Check how many right-children there are.\n\t\t\tconst rightChildrenCount = data.output.childCount - i - 1;\n\t\t\tlet rightParent = null;\n\n\t\t\t// If there are any right-children, clone the prent element and insert those children there.\n\t\t\tif ( rightChildrenCount > 0 ) {\n\t\t\t\trightParent = data.output.clone( false );\n\t\t\t\trightParent.appendChildren( data.output.removeChildren( i + 1, rightChildrenCount ) );\n\t\t\t}\n\n\t\t\t// Remove the autohoisted element from its parent.\n\t\t\tchild.remove();\n\n\t\t\t// Break \"leading\" `data.output` in `newOutput` into one or more pieces:\n\t\t\t// Remove \"leading\" `data.output` (note that `data.output` is always first item in `newOutput`).\n\t\t\tnewOutput.shift();\n\n\t\t\t// Add the newly created parent of the right-children at the beginning.\n\t\t\tif ( rightParent ) {\n\t\t\t\tnewOutput.unshift( rightParent );\n\t\t\t}\n\n\t\t\t// Add autohoisted element at the beginning.\n\t\t\tnewOutput.unshift( child );\n\n\t\t\t// Add `data.output` at the beginning, if there is anything left in it.\n\t\t\tif ( data.output.childCount > 0 ) {\n\t\t\t\tnewOutput.unshift( data.output );\n\t\t\t}\n\t\t}\n\t}\n\n\t// If the output has changed pass it further.\n\tif ( newOutput.length ) {\n\t\tdata.output = new ModelDocumentFragment( newOutput );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/image/converters.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module widget/highlightstack\n */\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Class used to handle correct order of\n * {@link module:engine/conversion/buildmodelconverter~ModelConverterBuilder#toHighlight highlights} on\n * elements. When different highlights are applied to same element correct order should be preserved:\n * * highlight with highest priority should be applied,\n * * if two highlights have same priority - sort by CSS class provided in\n * {@link module:engine/conversion/model-to-view-converters~HighlightDescriptor}.\n * This way, highlight will be applied with the same rules it is applied on texts.\n */\nexport default class HighlightStack {\n\t/**\n\t * Creates class instance.\n\t */\n\tconstructor() {\n\t\tthis._stack = [];\n\t}\n\n\t/**\n\t * Adds highlight descriptor to the stack.\n\t *\n\t * @fires change:top\n\t * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} descriptor\n\t */\n\tadd( descriptor ) {\n\t\tconst stack = this._stack;\n\n\t\t// Save top descriptor and insert new one. If top is changed - fire event.\n\t\tconst oldTop = stack[ 0 ];\n\t\tthis._insertDescriptor( descriptor );\n\t\tconst newTop = stack[ 0 ];\n\n\t\t// When new object is at the top and stores different information.\n\t\tif ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {\n\t\t\tthis.fire( 'change:top', {\n\t\t\t\toldDescriptor: oldTop,\n\t\t\t\tnewDescriptor: newTop\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Removes highlight descriptor from the stack.\n\t *\n\t * @fires change:top\n\t * @param {String} id Id of the descriptor to remove.\n\t */\n\tremove( id ) {\n\t\tconst stack = this._stack;\n\n\t\tconst oldTop = stack[ 0 ];\n\t\tthis._removeDescriptor( id );\n\t\tconst newTop = stack[ 0 ];\n\n\t\t// When new object is at the top and stores different information.\n\t\tif ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {\n\t\t\tthis.fire( 'change:top', {\n\t\t\t\toldDescriptor: oldTop,\n\t\t\t\tnewDescriptor: newTop\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Inserts given descriptor in correct place in the stack. It also takes care about updating information when\n\t * descriptor with same id is already present.\n\t *\n\t * @private\n\t * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} descriptor\n\t */\n\t_insertDescriptor( descriptor ) {\n\t\tconst stack = this._stack;\n\t\tconst index = stack.findIndex( item => item.id === descriptor.id );\n\n\t\t// Inserting exact same descriptor - do nothing.\n\t\tif ( compareDescriptors( descriptor, stack[ index ] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If descriptor with same id but with different information is on the stack - remove it.\n\t\tif ( index > -1 ) {\n\t\t\tstack.splice( index, 1 );\n\t\t}\n\n\t\t// Find correct place to insert descriptor in the stack.\n\t\t// It have different information (for example priority) so it must be re-inserted in correct place.\n\t\tlet i = 0;\n\n\t\twhile ( stack[ i ] && shouldABeBeforeB( stack[ i ], descriptor ) ) {\n\t\t\ti++;\n\t\t}\n\n\t\tstack.splice( i, 0, descriptor );\n\t}\n\n\t/**\n\t * Removes descriptor with given id from the stack.\n\t *\n\t * @private\n\t * @param {String} id Descriptor's id.\n\t */\n\t_removeDescriptor( id ) {\n\t\tconst stack = this._stack;\n\t\tconst index = stack.findIndex( item => item.id === id );\n\n\t\t// If descriptor with same id is on the list - remove it.\n\t\tif ( index > -1 ) {\n\t\t\tstack.splice( index, 1 );\n\t\t}\n\t}\n}\n\nmix( HighlightStack, EmitterMixin );\n\n// Compares two descriptors by checking their priority and class list.\n//\n// @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} a\n// @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} b\n// @returns {Boolean} Returns true if both descriptors are defined and have same priority and classes.\nfunction compareDescriptors( a, b ) {\n\treturn a && b && a.priority == b.priority && classesToString( a.class ) == classesToString( b.class );\n}\n\n// Checks whenever first descriptor should be placed in the stack before second one.\n//\n// @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} a\n// @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} b\n// @returns {Boolean}\nfunction shouldABeBeforeB( a, b ) {\n\tif ( a.priority > b.priority ) {\n\t\treturn true;\n\t} else if ( a.priority < b.priority ) {\n\t\treturn false;\n\t}\n\n\t// When priorities are equal and names are different - use classes to compare.\n\treturn classesToString( a.class ) > classesToString( b.class );\n}\n\n// Converts CSS classes passed with {@link module:engine/conversion/model-to-view-converters~HighlightDescriptor} to\n// sorted string.\n//\n// @param {String|Array<String>} descriptor\n// @returns {String}\nfunction classesToString( classes ) {\n\treturn Array.isArray( classes ) ? classes.sort().join( ',' ) : classes;\n}\n\n/**\n * Fired when top element on {@link module:widget/highlightstack~HighlightStack} has been changed\n *\n * @event change:top\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} [data.newDescriptor] New highlight\n * descriptor. It will be `undefined` when last descriptor is removed from the stack.\n * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor} [data.oldDescriptor] Old highlight\n * descriptor. It will be `undefined` when first descriptor is added to the stack.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-widget/src/highlightstack.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module widget/utils\n */\n\nimport HighlightStack from './highlightstack';\n\nconst widgetSymbol = Symbol( 'isWidget' );\nconst labelSymbol = Symbol( 'label' );\n\n/**\n * CSS class added to each widget element.\n *\n * @const {String}\n */\nexport const WIDGET_CLASS_NAME = 'ck-widget';\n\n/**\n * CSS class added to currently selected widget element.\n *\n * @const {String}\n */\nexport const WIDGET_SELECTED_CLASS_NAME = 'ck-widget_selected';\n\n/**\n * Returns `true` if given {@link module:engine/view/element~Element} is a widget.\n *\n * @param {module:engine/view/element~Element} element\n * @returns {Boolean}\n */\nexport function isWidget( element ) {\n\treturn !!element.getCustomProperty( widgetSymbol );\n}\n\n/**\n * Converts given {@link module:engine/view/element~Element} to widget in following way:\n * * sets `contenteditable` attribute to `\"true\"`,\n * * adds custom `getFillerOffset` method returning `null`,\n * * adds `ck-widget` CSS class,\n * * adds custom property allowing to recognize widget elements by using {@link ~isWidget},\n * * implements `addHighlight` and `removeHighlight` custom properties to handle view highlight on widgets.\n *\n * @param {module:engine/view/element~Element} element\n * @param {Object} [options={}]\n * @param {String|Function} [options.label] Element's label provided to {@link ~setLabel} function. It can be passed as\n * a plain string or a function returning a string.\n * @returns {module:engine/view/element~Element} Returns same element.\n */\nexport function toWidget( element, options = {} ) {\n\telement.setAttribute( 'contenteditable', 'false' );\n\telement.getFillerOffset = getFillerOffset;\n\telement.addClass( WIDGET_CLASS_NAME );\n\telement.setCustomProperty( widgetSymbol, true );\n\n\tif ( options.label ) {\n\t\tsetLabel( element, options.label );\n\t}\n\n\tsetHighlightHandling(\n\t\telement,\n\t\t( element, descriptor ) => element.addClass( ...normalizeToArray( descriptor.class ) ),\n\t\t( element, descriptor ) => element.removeClass( ...normalizeToArray( descriptor.class ) )\n\t);\n\n\treturn element;\n\n\t// Normalizes CSS class in descriptor that can be provided in form of an array or a string.\n\tfunction normalizeToArray( classes ) {\n\t\treturn Array.isArray( classes ) ? classes : [ classes ];\n\t}\n}\n\n/**\n * Sets highlight handling methods. Uses {@link module:widget/highlightstack~HighlightStack} to\n * properly determine which highlight descriptor should be used at given time.\n *\n * @param {module:engine/view/element~Element} element\n * @param {Function} add\n * @param {Function} remove\n */\nexport function setHighlightHandling( element, add, remove ) {\n\tconst stack = new HighlightStack();\n\n\tstack.on( 'change:top', ( evt, data ) => {\n\t\tif ( data.oldDescriptor ) {\n\t\t\tremove( element, data.oldDescriptor );\n\t\t}\n\n\t\tif ( data.newDescriptor ) {\n\t\t\tadd( element, data.newDescriptor );\n\t\t}\n\t} );\n\n\telement.setCustomProperty( 'addHighlight', ( element, descriptor ) => stack.add( descriptor ) );\n\telement.setCustomProperty( 'removeHighlight', ( element, id ) => stack.remove( id ) );\n}\n\n/**\n * Sets label for given element.\n * It can be passed as a plain string or a function returning a string. Function will be called each time label is retrieved by\n * {@link ~getLabel}.\n *\n * @param {module:engine/view/element~Element} element\n * @param {String|Function} labelOrCreator\n */\nexport function setLabel( element, labelOrCreator ) {\n\telement.setCustomProperty( labelSymbol, labelOrCreator );\n}\n\n/**\n * Returns label for provided element.\n *\n * @param {module:engine/view/element~Element} element\n * @return {String}\n */\nexport function getLabel( element ) {\n\tconst labelCreator = element.getCustomProperty( labelSymbol );\n\n\tif ( !labelCreator ) {\n\t\treturn '';\n\t}\n\n\treturn typeof labelCreator == 'function' ? labelCreator() : labelCreator;\n}\n\n/**\n * Adds functionality to provided {module:engine/view/editableelement~EditableElement} to act as a widget's editable:\n * * adds `ck-editable` CSS class,\n * * sets `contenteditable` as `true` when {module:engine/view/editableelement~EditableElement#isReadOnly} is `false`\n * otherwise set `false`,\n * * adds `ck-editable_focused` CSS class when editable is focused and removes it when it's blurred.\n *\n * @param {module:engine/view/editableelement~EditableElement} editable\n * @returns {module:engine/view/editableelement~EditableElement} Returns same element that was provided in `editable` param.\n */\nexport function toWidgetEditable( editable ) {\n\teditable.addClass( 'ck-editable' );\n\n\t// Set initial contenteditable value.\n\teditable.setAttribute( 'contenteditable', editable.isReadOnly ? 'false' : 'true' );\n\n\t// Bind contenteditable property to element#isReadOnly.\n\teditable.on( 'change:isReadOnly', ( evt, property, is ) => {\n\t\teditable.setAttribute( 'contenteditable', is ? 'false' : 'true' );\n\t} );\n\n\teditable.on( 'change:isFocused', ( evt, property, is ) => {\n\t\tif ( is ) {\n\t\t\teditable.addClass( 'ck-editable_focused' );\n\t\t} else {\n\t\t\teditable.removeClass( 'ck-editable_focused' );\n\t\t}\n\t} );\n\n\treturn editable;\n}\n\n// Default filler offset function applied to all widget elements.\n//\n// @returns {null}\nfunction getFillerOffset() {\n\treturn null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-widget/src/utils.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image/utils\n */\n\nimport { toWidget, isWidget } from '@ckeditor/ckeditor5-widget/src/utils';\nimport ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';\n\nconst imageSymbol = Symbol( 'isImage' );\n\n/**\n * Converts a given {@link module:engine/view/element~Element} to an image widget:\n * * adds a {@link module:engine/view/element~Element#setCustomProperty custom property} allowing to recognize the image widget element,\n * * calls the {@link module:widget/utils~toWidget toWidget} function with the proper element's label creator.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @param {String} label Element's label. It will be concatenated with the image `alt` attribute if one is present.\n * @returns {module:engine/view/element~Element}\n */\nexport function toImageWidget( viewElement, label ) {\n\tviewElement.setCustomProperty( imageSymbol, true );\n\n\treturn toWidget( viewElement, { label: labelCreator } );\n\n\tfunction labelCreator() {\n\t\tconst imgElement = viewElement.getChild( 0 );\n\t\tconst altText = imgElement.getAttribute( 'alt' );\n\n\t\treturn altText ? `${ altText } ${ label }` : label;\n\t}\n}\n\n/**\n * Checks if a given view element is an image widget.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isImageWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( imageSymbol ) && isWidget( viewElement );\n}\n\n/**\n * Checks if an image widget is the only selected element.\n *\n * @param {module:engine/view/selection~Selection} viewSelection\n * @returns {Boolean}\n */\nexport function isImageWidgetSelected( viewSelection ) {\n\tconst viewElement = viewSelection.getSelectedElement();\n\n\treturn !!( viewElement && isImageWidget( viewElement ) );\n}\n\n/**\n * Checks if the provided model element is an instance of {@link module:engine/model/element~Element Element} and its name\n * is `image`.\n *\n * @param {module:engine/model/element~Element} modelElement\n * @returns {Boolean}\n */\nexport function isImage( modelElement ) {\n\treturn modelElement instanceof ModelElement && modelElement.name == 'image';\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/image/utils.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/image/imageengine\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';\nimport buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';\nimport {\n viewFigureToModel,\n createImageAttributeConverter,\n convertHoistableImage,\n hoistImageThroughElement,\n srcsetAttributeConverter\n} from './converters';\nimport { toImageWidget } from './utils';\nimport ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';\nimport ViewContainerElement from '@ckeditor/ckeditor5-engine/src/view/containerelement';\nimport ViewEmptyElement from '@ckeditor/ckeditor5-engine/src/view/emptyelement';\n/**\n * The image engine plugin.\n * Registers `<image>` as a block element in the document schema, and allows `alt`, `src` and `srcset` attributes.\n * Registers converters for editing and data pipelines.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageEngine extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const doc = editor.document;\n const schema = doc.schema;\n const data = editor.data;\n const editing = editor.editing;\n const t = editor.t;\n // Configure schema.\n schema.registerItem('image');\n schema.requireAttributes('image', ['src']);\n schema.allow({\n name: 'image',\n attributes: [\n 'alt',\n 'src',\n 'srcset'\n ],\n inside: '$root'\n });\n schema.objects.add('image');\n // Build converter from model to view for data pipeline.\n buildModelConverter().for(data.modelToView).fromElement('image').toElement(() => createImageViewElement());\n // Build converter from model to view for editing pipeline.\n buildModelConverter().for(editing.modelToView).fromElement('image').toElement(() => toImageWidget(createImageViewElement(), t('image widget')));\n createImageAttributeConverter([\n editing.modelToView,\n data.modelToView\n ], 'src');\n createImageAttributeConverter([\n editing.modelToView,\n data.modelToView\n ], 'alt');\n // Convert `srcset` attribute changes and add or remove `sizes` attribute when necessary.\n createImageAttributeConverter([\n editing.modelToView,\n data.modelToView\n ], 'srcset', srcsetAttributeConverter);\n // Build converter for view img element to model image element.\n buildViewConverter().for(data.viewToModel).from({\n name: 'img',\n attribute: { src: /./ }\n }).toElement(viewImage => new ModelElement('image', { src: viewImage.getAttribute('src') }));\n data.viewToModel.on('element:img', convertHoistableImage, { priority: 'low' });\n data.viewToModel.on('element', hoistImageThroughElement, { priority: 'low' });\n // Build converter for alt attribute.\n // Note that by default attribute converters are added with `low` priority.\n // This converter will be thus fired after `convertHoistableImage` converter.\n buildViewConverter().for(data.viewToModel).from({\n name: 'img',\n attribute: { alt: /./ }\n }).consuming({ attribute: ['alt'] }).toAttribute(viewImage => ({\n key: 'alt',\n value: viewImage.getAttribute('alt')\n }));\n // Build converter for srcset attribute.\n buildViewConverter().for(data.viewToModel).from({\n name: 'img',\n attribute: { srcset: /./ }\n }).consuming({ attribute: ['srcset'] }).toAttribute(viewImage => {\n const value = { data: viewImage.getAttribute('srcset') };\n if (viewImage.hasAttribute('width')) {\n value.width = viewImage.getAttribute('width');\n }\n return {\n key: 'srcset',\n value\n };\n });\n // Converter for figure element from view to model.\n data.viewToModel.on('element:figure', viewFigureToModel());\n }\n}\n// Creates a view element representing the image.\n//\n//\t\t<figure class=\"image\"><img></img></figure>\n//\n// Note that `alt` and `src` attributes are converted separately, so they are not included.\n//\n// @private\n// @return {module:engine/view/containerelement~ContainerElement}\nexport function createImageViewElement() {\n return new ViewContainerElement('figure', { class: 'image' }, new ViewEmptyElement('img'));\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/image/imageengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/mouseobserver\n */\n\nimport DomEventObserver from './domeventobserver';\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/document~Document}\n * by {@link module:engine/view/document~Document#addObserver} method.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class MouseObserver extends DomEventObserver {\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\tthis.domEventType = 'mousedown';\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when mouse button is pressed down on one of the editables.\n *\n * Introduced by {@link module:engine/view/observer/mouseobserver~MouseObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:engine/view/observer/mouseobserver~MouseObserver}\n * needs to be added to {@link module:engine/view/document~Document} by a {@link module:engine/view/document~Document#addObserver} method.\n *\n * @see module:engine/view/observer/mouseobserver~MouseObserver\n * @event module:engine/view/document~Document#event:mousedown\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/mouseobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module widget/widget\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';\nimport ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';\nimport ModelSelection from '@ckeditor/ckeditor5-engine/src/model/selection';\nimport ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';\nimport ViewEditableElement from '@ckeditor/ckeditor5-engine/src/view/editableelement';\nimport RootEditableElement from '@ckeditor/ckeditor5-engine/src/view/rooteditableelement';\nimport { isWidget, WIDGET_SELECTED_CLASS_NAME, getLabel } from './utils';\nimport { keyCodes, getCode, parseKeystroke } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\nimport '../theme/theme.scss';\n\nconst selectAllKeystrokeCode = parseKeystroke( 'Ctrl+A' );\n\n/**\n * The widget plugin.\n * Registers model to view selection converter for editing pipeline. It is hooked after default selection conversion.\n * If converted selection is placed around widget element, selection is marked as fake. Additionally, proper CSS class\n * is added to indicate that widget has been selected.\n * Adds default {@link module:engine/view/document~Document#event:mousedown mousedown} handling on widget elements.\n *\n * @extends module:core/plugin~Plugin.\n */\nexport default class Widget extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Widget';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst viewDocument = this.editor.editing.view;\n\n\t\t/**\n\t\t * Holds previously selected widgets.\n\t\t *\n\t\t * @private\n\t\t * @type {Set.<module:engine/view/element~Element>}\n\t\t */\n\t\tthis._previouslySelected = new Set();\n\n\t\t// Model to view selection converter.\n\t\t// Converts selection placed over widget element to fake selection\n\t\tthis.editor.editing.modelToView.on( 'selection', ( evt, data, consumable, conversionApi ) => {\n\t\t\t// Remove selected class from previously selected widgets.\n\t\t\tthis._clearPreviouslySelectedWidgets();\n\n\t\t\tconst viewSelection = conversionApi.viewSelection;\n\t\t\tconst selectedElement = viewSelection.getSelectedElement();\n\n\t\t\tfor ( const range of viewSelection.getRanges() ) {\n\t\t\t\tfor ( const value of range ) {\n\t\t\t\t\tconst node = value.item;\n\n\t\t\t\t\tif ( node.is( 'element' ) && isWidget( node ) ) {\n\t\t\t\t\t\tnode.addClass( WIDGET_SELECTED_CLASS_NAME );\n\t\t\t\t\t\tthis._previouslySelected.add( node );\n\n\t\t\t\t\t\t// Check if widget is a single element selected.\n\t\t\t\t\t\tif ( node == selectedElement ) {\n\t\t\t\t\t\t\tviewSelection.setFake( true, { label: getLabel( selectedElement ) } );\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}, { priority: 'low' } );\n\n\t\t// If mouse down is pressed on widget - create selection over whole widget.\n\t\tviewDocument.addObserver( MouseObserver );\n\t\tthis.listenTo( viewDocument, 'mousedown', ( ...args ) => this._onMousedown( ...args ) );\n\n\t\t// Handle custom keydown behaviour.\n\t\tthis.listenTo( viewDocument, 'keydown', ( ...args ) => this._onKeydown( ...args ), { priority: 'high' } );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_onMousedown( eventInfo, domEventData ) {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view;\n\t\tlet element = domEventData.target;\n\n\t\t// Do nothing if inside nested editable.\n\t\tif ( isInsideNestedEditable( element ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If target is not a widget element - check if one of the ancestors is.\n\t\tif ( !isWidget( element ) ) {\n\t\t\telement = element.findAncestor( isWidget );\n\n\t\t\tif ( !element ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tdomEventData.preventDefault();\n\n\t\t// Focus editor if is not focused already.\n\t\tif ( !viewDocument.isFocused ) {\n\t\t\tviewDocument.focus();\n\t\t}\n\n\t\t// Create model selection over widget.\n\t\tconst modelElement = editor.editing.mapper.toModelElement( element );\n\n\t\teditor.document.enqueueChanges( ( ) => {\n\t\t\tthis._setSelectionOverElement( modelElement );\n\t\t} );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_onKeydown( eventInfo, domEventData ) {\n\t\tconst keyCode = domEventData.keyCode;\n\t\tconst isForward = keyCode == keyCodes.delete || keyCode == keyCodes.arrowdown || keyCode == keyCodes.arrowright;\n\t\tlet wasHandled = false;\n\n\t\t// Checks if the keys were handled and then prevents the default event behaviour and stops\n\t\t// the propagation.\n\t\tif ( isDeleteKeyCode( keyCode ) ) {\n\t\t\twasHandled = this._handleDelete( isForward );\n\t\t} else if ( isArrowKeyCode( keyCode ) ) {\n\t\t\twasHandled = this._handleArrowKeys( isForward );\n\t\t} else if ( isSelectAllKeyCode( domEventData ) ) {\n\t\t\twasHandled = this._selectAllNestedEditableContent() || this._selectAllContent();\n\t\t}\n\n\t\tif ( wasHandled ) {\n\t\t\tdomEventData.preventDefault();\n\t\t\teventInfo.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles delete keys: backspace and delete.\n\t *\n\t * @private\n\t * @param {Boolean} isForward Set to true if delete was performed in forward direction.\n\t * @returns {Boolean|undefined} Returns `true` if keys were handled correctly.\n\t */\n\t_handleDelete( isForward ) {\n\t\t// Do nothing when the read only mode is enabled.\n\t\tif ( this.editor.isReadOnly ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelDocument = this.editor.document;\n\t\tconst modelSelection = modelDocument.selection;\n\n\t\t// Do nothing on non-collapsed selection.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst objectElement = this._getObjectElementNextToSelection( isForward );\n\n\t\tif ( objectElement ) {\n\t\t\tmodelDocument.enqueueChanges( () => {\n\t\t\t\tconst batch = modelDocument.batch();\n\t\t\t\tlet previousNode = modelSelection.anchor.parent;\n\n\t\t\t\t// Remove previous element if empty.\n\t\t\t\twhile ( previousNode.isEmpty ) {\n\t\t\t\t\tconst nodeToRemove = previousNode;\n\t\t\t\t\tpreviousNode = nodeToRemove.parent;\n\n\t\t\t\t\tbatch.remove( nodeToRemove );\n\t\t\t\t}\n\n\t\t\t\tthis._setSelectionOverElement( objectElement );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * Handles arrow keys.\n\t *\n\t * @param {Boolean} isForward Set to true if arrow key should be handled in forward direction.\n\t * @returns {Boolean|undefined} Returns `true` if keys were handled correctly.\n\t */\n\t_handleArrowKeys( isForward ) {\n\t\tconst modelDocument = this.editor.document;\n\t\tconst schema = modelDocument.schema;\n\t\tconst modelSelection = modelDocument.selection;\n\t\tconst objectElement = modelSelection.getSelectedElement();\n\n\t\t// if object element is selected.\n\t\tif ( objectElement && schema.objects.has( objectElement.name ) ) {\n\t\t\tconst position = isForward ? modelSelection.getLastPosition() : modelSelection.getFirstPosition();\n\t\t\tconst newRange = modelDocument.getNearestSelectionRange( position, isForward ? 'forward' : 'backward' );\n\n\t\t\tif ( newRange ) {\n\t\t\t\tmodelDocument.enqueueChanges( () => {\n\t\t\t\t\tmodelSelection.setRanges( [ newRange ] );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\t// If selection is next to object element.\n\t\t// Return if not collapsed.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst objectElement2 = this._getObjectElementNextToSelection( isForward );\n\n\t\tif ( objectElement2 instanceof ModelElement && modelDocument.schema.objects.has( objectElement2.name ) ) {\n\t\t\tmodelDocument.enqueueChanges( () => {\n\t\t\t\tthis._setSelectionOverElement( objectElement2 );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * Extends the {@link module:engine/model/selection~Selection document's selection} to span the entire\n\t * content of the nested editable if already anchored in one.\n\t *\n\t * See: {@link module:engine/model/schema~Schema#getLimitElement}.\n\t *\n\t * @private\n\t */\n\t_selectAllNestedEditableContent() {\n\t\tconst modelDocument = this.editor.document;\n\t\tconst modelSelection = modelDocument.selection;\n\t\tconst schema = modelDocument.schema;\n\t\tconst limitElement = schema.getLimitElement( modelSelection );\n\n\t\tif ( modelSelection.getFirstRange().root == limitElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tmodelDocument.enqueueChanges( () => {\n\t\t\tmodelSelection.setIn( limitElement );\n\t\t} );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Handles <kbd>CTRL + A</kbd> when widget is selected.\n\t *\n\t * @private\n\t * @returns {Boolean} Returns true if widget was selected and selecting all was handled by this method.\n\t */\n\t_selectAllContent() {\n\t\tconst modelDocument = this.editor.document;\n\t\tconst modelSelection = modelDocument.selection;\n\t\tconst editing = this.editor.editing;\n\t\tconst viewDocument = editing.view;\n\t\tconst viewSelection = viewDocument.selection;\n\n\t\tconst selectedElement = viewSelection.getSelectedElement();\n\n\t\t// Only widget is selected.\n\t\t// https://github.com/ckeditor/ckeditor5-widget/issues/23\n\t\tif ( selectedElement && isWidget( selectedElement ) ) {\n\t\t\tconst widgetParent = editing.mapper.toModelElement( selectedElement.parent );\n\n\t\t\tmodelDocument.enqueueChanges( () => {\n\t\t\t\tmodelSelection.setRanges( [ ModelRange.createIn( widgetParent ) ] );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Sets {@link module:engine/model/selection~Selection document's selection} over given element.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} element\n\t */\n\t_setSelectionOverElement( element ) {\n\t\tthis.editor.document.selection.setRanges( [ ModelRange.createOn( element ) ] );\n\t}\n\n\t/**\n\t * Checks if {@link module:engine/model/element~Element element} placed next to the current\n\t * {@link module:engine/model/selection~Selection model selection} exists and is marked in\n\t * {@link module:engine/model/schema~Schema schema} as `object`.\n\t *\n\t * @private\n\t * @param {Boolean} forward Direction of checking.\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\t_getObjectElementNextToSelection( forward ) {\n\t\tconst modelDocument = this.editor.document;\n\t\tconst schema = modelDocument.schema;\n\t\tconst modelSelection = modelDocument.selection;\n\t\tconst dataController = this.editor.data;\n\n\t\t// Clone current selection to use it as a probe. We must leave default selection as it is so it can return\n\t\t// to its current state after undo.\n\t\tconst probe = ModelSelection.createFromSelection( modelSelection );\n\t\tdataController.modifySelection( probe, { direction: forward ? 'forward' : 'backward' } );\n\t\tconst objectElement = forward ? probe.focus.nodeBefore : probe.focus.nodeAfter;\n\n\t\tif ( objectElement instanceof ModelElement && schema.objects.has( objectElement.name ) ) {\n\t\t\treturn objectElement;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Removes CSS class from previously selected widgets.\n\t * @private\n\t */\n\t_clearPreviouslySelectedWidgets() {\n\t\tfor ( const widget of this._previouslySelected ) {\n\t\t\twidget.removeClass( WIDGET_SELECTED_CLASS_NAME );\n\t\t}\n\n\t\tthis._previouslySelected.clear();\n\t}\n}\n\n// Returns 'true' if provided key code represents one of the arrow keys.\n//\n// @param {Number} keyCode\n// @returns {Boolean}\nfunction isArrowKeyCode( keyCode ) {\n\treturn keyCode == keyCodes.arrowright ||\n\t\tkeyCode == keyCodes.arrowleft ||\n\t\tkeyCode == keyCodes.arrowup ||\n\t\tkeyCode == keyCodes.arrowdown;\n}\n\n// Returns 'true' if provided key code represents one of the delete keys: delete or backspace.\n//\n// @param {Number} keyCode\n// @returns {Boolean}\nfunction isDeleteKeyCode( keyCode ) {\n\treturn keyCode == keyCodes.delete || keyCode == keyCodes.backspace;\n}\n\n// Returns 'true' if provided (DOM) key event data corresponds with the Ctrl+A keystroke.\n//\n// @param {module:engine/view/observer/keyobserver~KeyEventData} domEventData\n// @returns {Boolean}\nfunction isSelectAllKeyCode( domEventData ) {\n\treturn getCode( domEventData ) == selectAllKeystrokeCode;\n}\n\n// Returns `true` when element is a nested editable or is placed inside one.\n//\n// @param {module:engine/view/element~Element}\n// @returns {Boolean}\nfunction isInsideNestedEditable( element ) {\n\twhile ( element ) {\n\t\tif ( element instanceof ViewEditableElement && !( element instanceof RootEditableElement ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\telement = element.parent;\n\t}\n\n\treturn false;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-widget/src/widget.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagetextalternative/imagetextalternativecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { isImage } from '../image/utils';\n\n/**\n * The image text alternative command. It is used to change the `alt` attribute on `<image>` elements.\n *\n * @extends module:core/command~Command\n */\nexport default class ImageTextAlternativeCommand extends Command {\n\t/**\n\t * The command value: `false` if there is no `alt` attribute, otherwise the value of the `alt` attribute.\n\t *\n\t * @readonly\n\t * @observable\n\t * @member {String|Boolean} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst element = this.editor.document.selection.getSelectedElement();\n\n\t\tthis.isEnabled = isImage( element );\n\n\t\tif ( isImage( element ) && element.hasAttribute( 'alt' ) ) {\n\t\t\tthis.value = element.getAttribute( 'alt' );\n\t\t} else {\n\t\t\tthis.value = false;\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {String} options.newValue The new value of the `alt` attribute to set.\n\t * @param {module:engine/model/batch~Batch} [options.batch] A batch to collect all the change steps. A new batch will be\n\t * created if this option is not set.\n\t */\n\texecute( options ) {\n\t\tconst doc = this.editor.document;\n\t\tconst imageElement = doc.selection.getSelectedElement();\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tconst batch = options.batch || doc.batch();\n\n\t\t\tbatch.setAttribute( imageElement, 'alt', options.newValue );\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagetextalternative/imagetextalternativecommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/bindings/clickoutsidehandler\n */\n\n/* global document */\n\n/**\n * Handles clicking **outside** of a specified set of elements, then fires an action.\n *\n * **Note**: Actually, the action is executed upon `mousedown`, not `click`. It prevents\n * certain issues when the user keeps holding the mouse button and the UI cannot react\n * properly.\n *\n * @param {Object} options Configuration options.\n * @param {module:utils/dom/emittermixin~Emitter} options.emitter The emitter to which this behavior\n * should be added.\n * @param {Function} options.activator Function returning a `Boolean`, to determine whether the handler is active.\n * @param {Array.<HTMLElement>} options.contextElements HTML elements that determine the scope of the\n * handler. Clicking any of them or their descendants will **not** fire the callback.\n * @param {Function} options.callback An action executed by the handler.\n */\nexport default function clickOutsideHandler( { emitter, activator, callback, contextElements } ) {\n\temitter.listenTo( document, 'mousedown', ( evt, { target } ) => {\n\t\tif ( !activator() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const contextElement of contextElements ) {\n\t\t\tif ( contextElement.contains( target ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tcallback();\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/bindings/clickoutsidehandler.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/label/labelview\n */\n\nimport View from '../view';\n\n/**\n * The label view class.\n *\n * @extends module:ui/view~View\n */\nexport default class LabelView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The text of the label.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #text\n\t\t */\n\t\tthis.set( 'text' );\n\n\t\t/**\n\t\t * The `for` attribute of the label (i.e. to pair with an `<input>` element).\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #for\n\t\t */\n\t\tthis.set( 'for' );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'label',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-label'\n\t\t\t\t],\n\t\t\t\tfor: bind.to( 'for' )\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: bind.to( 'text' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/label/labelview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/bindings/submithandler\n */\n\n/**\n * A handler useful for {@link module:ui/view~View views} working as HTML forms. It intercepts a native DOM\n * `submit` event, prevents the default web browser behavior (navigation and page reload) and\n * fires the `submit` event on a view instead. Such a custom event can be then used by any\n * {@link module:utils/dom/emittermixin~Emitter emitter}, e.g. to serialize the form data.\n *\n *\t\timport submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';\n *\n *\t\t// ...\n *\n *\t\tclass AnyFormView extends View {\n *\t\t\tconstructor() {\n *\t\t\t\tsuper();\n *\n *\t\t\t\t// ...\n *\n *\t\t\t\tsubmitHandler( {\n *\t\t\t\t\tview: this\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n *\t\t// ...\n *\n *\t\tconst view = new AnyFormView();\n *\n *\t\t// A sample listener attached by an emitter working with the view.\n *\t\tthis.listenTo( view, 'submit', () => {\n *\t\t\tsaveTheFormData();\n *\t\t\thideTheForm();\n *\t\t} );\n *\n * @param {Object} [options] Configuration options.\n * @param {module:ui/view~View} options.view The view which DOM `submit` events should be handled.\n */\nexport default function submitHandler( { view } ) {\n\tview.listenTo( view.element, 'submit', ( evt, domEvt ) => {\n\t\tdomEvt.preventDefault();\n\t\tview.fire( 'submit' );\n\t}, { useCapture: true } );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/bindings/submithandler.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imagetextalternative/ui/textalternativeformview\n */\nimport View from '@ckeditor/ckeditor5-ui/src/view';\nimport ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport LabeledInputView from '@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview';\nimport InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview';\nimport submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';\n/**\n * The TextAlternativeFormView class.\n *\n * @extends module:ui/view~View\n */\nexport default class TextAlternativeFormView extends View {\n /**\n\t * @inheritDoc\n\t */\n constructor(locale) {\n super(locale);\n const t = this.locale.t;\n /**\n\t\t * Tracks information about DOM focus in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n this.focusTracker = new FocusTracker();\n /**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n this.keystrokes = new KeystrokeHandler();\n /**\n\t\t * A textarea with a label.\n\t\t *\n\t\t * @member {module:ui/labeledinput/labeledinputview~LabeledInputView} #labeledTextarea\n\t\t */\n this.labeledInput = this._createLabeledInputView();\n /**\n\t\t * A button used to submit the form.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView} #saveButtonView\n\t\t */\n this.saveButtonView = this._createButton(t('Save'));\n this.saveButtonView.type = 'submit';\n /**\n\t\t * A button used to cancel the form.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView} #cancelButtonView\n\t\t */\n this.cancelButtonView = this._createButton(t('Cancel'), 'cancel');\n /**\n\t\t * A collection of views which can be focused in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n this._focusables = new ViewCollection();\n /**\n\t\t * Helps cycling over {@link #_focusables} in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n this._focusCycler = new FocusCycler({\n focusables: this._focusables,\n focusTracker: this.focusTracker,\n keystrokeHandler: this.keystrokes,\n actions: {\n // Navigate form fields backwards using the Shift + Tab keystroke.\n focusPrevious: 'shift + tab',\n // Navigate form fields forwards using the Tab key.\n focusNext: 'tab'\n }\n });\n this.saveButtonView.extendTemplate({ attributes: { class: ['ck-button-action'] } });\n this.setTemplate({\n tag: 'form',\n attributes: {\n class: ['cke-text-alternative-form'],\n // https://github.com/ckeditor/ckeditor5-image/issues/40\n tabindex: '-1'\n },\n children: [\n this.labeledInput,\n {\n tag: 'div',\n attributes: { class: ['cke-text-alternative-form__actions'] },\n children: [\n this.saveButtonView,\n this.cancelButtonView\n ]\n }\n ]\n });\n }\n /**\n\t * @inheritDoc\n\t */\n render() {\n super.render();\n this.keystrokes.listenTo(this.element);\n submitHandler({ view: this });\n [\n this.labeledInput,\n this.saveButtonView,\n this.cancelButtonView\n ].forEach(v => {\n // Register the view as focusable.\n this._focusables.add(v);\n // Register the view in the focus tracker.\n this.focusTracker.add(v.element);\n });\n }\n /**\n\t * Creates the button view.\n\t *\n\t * @private\n\t * @param {String} label The button label\n\t * @param {String} [eventName] The event name that the ButtonView#execute event will be delegated to.\n\t * @returns {module:ui/button/buttonview~ButtonView} The button view instance.\n\t */\n _createButton(label, eventName) {\n const button = new ButtonView(this.locale);\n button.label = label;\n button.withText = true;\n if (eventName) {\n button.delegate('execute').to(this, eventName);\n }\n return button;\n }\n /**\n\t * Creates an input with a label.\n\t *\n\t * @private\n\t * @return {module:ui/labeledinput/labeledinputview~LabeledInputView}\n\t */\n _createLabeledInputView() {\n const t = this.locale.t;\n const labeledInput = new LabeledInputView(this.locale, InputTextView);\n labeledInput.label = t('Text alternative');\n return labeledInput;\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagetextalternative/ui/textalternativeformview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image/ui/utils\n */\n\nimport BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';\nimport { isImageWidgetSelected } from '../utils';\n\n/**\n * A helper utility which positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon} instance\n * with respect to the image in the editor content, if one is selected.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n */\nexport function repositionContextualBalloon( editor ) {\n\tconst balloon = editor.plugins.get( 'ContextualBalloon' );\n\n\tif ( isImageWidgetSelected( editor.editing.view.selection ) ) {\n\t\tconst position = getBalloonPositionData( editor );\n\n\t\tballoon.updatePosition( position );\n\t}\n}\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}, with respect\n * to the selected element in the editor content.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n * @returns {module:utils/dom/position~Options}\n */\nexport function getBalloonPositionData( editor ) {\n\tconst editingView = editor.editing.view;\n\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\n\treturn {\n\t\ttarget: editingView.domConverter.viewToDom( editingView.selection.getSelectedElement() ),\n\t\tpositions: [\n\t\t\tdefaultPositions.northArrowSouth,\n\t\t\tdefaultPositions.southArrowNorth\n\t\t]\n\t};\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/image/ui/utils.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module upload/utils\n */\n\nimport ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';\n\n/**\n * Checks if given file is an image.\n *\n * @param {File} file\n * @returns {Boolean}\n */\nexport function isImageType( file ) {\n\tconst types = /^image\\/(jpeg|png|gif|bmp)$/;\n\n\treturn types.test( file.type );\n}\n\n/**\n * Returns a model position which is optimal (in terms of UX) for inserting an image.\n *\n * For instance, if a selection is in a middle of a paragraph, position before this paragraph\n * will be returned, so that it's not split. If the selection is at the end of a paragraph,\n * position after this paragraph will be returned.\n *\n * Note: If selection is placed in an empty block, that block will be returned. If that position\n * is then passed to {@link module:engine/controller/datacontroller~DataController#insertContent}\n * that block will be fully replaced by the image.\n *\n * @param {module:engine/model/selection~Selection} selection Selection based on which the\n * insertion position should be calculated.\n * @returns {module:engine/model/position~Position} The optimal position.\n */\nexport function findOptimalInsertionPosition( selection ) {\n\tconst selectedElement = selection.getSelectedElement();\n\n\tif ( selectedElement ) {\n\t\treturn ModelPosition.createAfter( selectedElement );\n\t}\n\n\tconst firstBlock = selection.getSelectedBlocks().next().value;\n\n\tif ( firstBlock ) {\n\t\t// If inserting into an empty block return position in that block. It will get\n\t\t// replaced with the image by insertContent(). #42.\n\t\tif ( firstBlock.isEmpty ) {\n\t\t\treturn ModelPosition.createAt( firstBlock );\n\t\t}\n\n\t\tconst positionAfter = ModelPosition.createAfter( firstBlock );\n\n\t\t// If selection is at the end of the block - return position after the block.\n\t\tif ( selection.focus.isTouching( positionAfter ) ) {\n\t\t\treturn positionAfter;\n\t\t}\n\n\t\t// Otherwise return position before the block.\n\t\treturn ModelPosition.createBefore( firstBlock );\n\t}\n\n\treturn selection.focus;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/utils.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module upload/imageuploadengine\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport FileRepository from './filerepository';\nimport ImageUploadCommand from './imageuploadcommand';\nimport Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';\nimport ModelSelection from '@ckeditor/ckeditor5-engine/src/model/selection';\nimport {\n isImageType,\n findOptimalInsertionPosition\n} from './utils';\n/**\n * Image upload engine plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadEngine extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [\n FileRepository,\n Notification\n ];\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const doc = editor.document;\n const schema = doc.schema;\n const fileRepository = editor.plugins.get(FileRepository);\n // Setup schema to allow uploadId for images.\n schema.allow({\n name: 'image',\n attributes: ['uploadId'],\n inside: '$root'\n });\n schema.allow({\n name: 'image',\n attributes: ['uploadStatus'],\n inside: '$root'\n });\n schema.requireAttributes('image', ['uploadId']);\n // Register imageUpload command.\n editor.commands.add('imageUpload', new ImageUploadCommand(editor));\n // Execute imageUpload command when image is dropped or pasted.\n editor.editing.view.on('clipboardInput', (evt, data) => {\n // Skip if non empty HTML data is included.\n // https://github.com/ckeditor/ckeditor5-upload/issues/68\n if (isHtmlIncluded(data.dataTransfer)) {\n return;\n }\n let targetModelSelection = new ModelSelection(data.targetRanges.map(viewRange => editor.editing.mapper.toModelRange(viewRange)));\n for (const file of data.dataTransfer.files) {\n const insertAt = findOptimalInsertionPosition(targetModelSelection);\n if (isImageType(file)) {\n editor.execute('imageUpload', {\n file,\n insertAt\n });\n evt.stop();\n }\n // Use target ranges only for the first image. Then, use that image position\n // so we keep adding the next ones after the previous one.\n targetModelSelection = doc.selection;\n }\n });\n // Prevents from browser redirecting to the dropped image.\n editor.editing.view.on('dragover', (evt, data) => {\n data.preventDefault();\n });\n doc.on('change', (evt, type, data) => {\n // Listen on document changes and:\n // * start upload process when image with `uploadId` attribute is inserted,\n // * abort upload process when image `uploadId` attribute is removed.\n if (type === 'insert' || type === 'reinsert' || type === 'remove') {\n for (const value of data.range) {\n if (value.type === 'elementStart' && value.item.name === 'image') {\n const imageElement = value.item;\n const uploadId = imageElement.getAttribute('uploadId');\n if (uploadId) {\n const loader = fileRepository.loaders.get(uploadId);\n if (loader) {\n if (type === 'insert' && loader.status == 'idle') {\n this.load(loader, imageElement);\n }\n if (type === 'remove') {\n loader.abort();\n }\n }\n }\n }\n }\n }\n });\n }\n /**\n\t * Performs image loading. Image is read from the disk and temporary data is displayed, after uploading process\n\t * is complete we replace temporary data with target image from the server.\n\t *\n\t * @protected\n\t * @param {module:upload/filerepository~FileLoader} loader\n\t * @param {module:engine/model/element~Element} imageElement\n\t */\n load(loader, imageElement) {\n const editor = this.editor;\n const t = editor.locale.t;\n const doc = editor.document;\n const fileRepository = editor.plugins.get(FileRepository);\n const notification = editor.plugins.get(Notification);\n doc.enqueueChanges(() => {\n doc.batch('transparent').setAttribute(imageElement, 'uploadStatus', 'reading');\n });\n loader.read().then(data => {\n const viewFigure = editor.editing.mapper.toViewElement(imageElement);\n const viewImg = viewFigure.getChild(0);\n const promise = loader.upload();\n viewImg.setAttribute('src', data);\n editor.editing.view.render();\n doc.enqueueChanges(() => {\n doc.batch('transparent').setAttribute(imageElement, 'uploadStatus', 'uploading');\n });\n return promise;\n }).then(data => {\n doc.enqueueChanges(() => {\n doc.batch('transparent').setAttribute(imageElement, 'uploadStatus', 'complete');\n doc.batch('transparent').setAttribute(imageElement, 'src', data.default);\n // Srcset attribute for responsive images support.\n let maxWidth = 0;\n const srcsetAttribute = Object.keys(data) // Filter out keys that are not integers.\n.filter(key => {\n const width = parseInt(key, 10);\n if (!isNaN(width)) {\n maxWidth = Math.max(maxWidth, width);\n return true;\n }\n }) // Convert each key to srcset entry.\n.map(key => `${ data[key] } ${ key }w`) // Join all entries.\n.join(', ');\n if (srcsetAttribute != '') {\n doc.batch('transparent').setAttribute(imageElement, 'srcset', {\n data: srcsetAttribute,\n width: maxWidth\n });\n }\n });\n clean();\n }).catch(msg => {\n // Might be 'aborted'.\n if (loader.status == 'error') {\n notification.showWarning(msg, {\n title: t('Upload failed'),\n namespace: 'upload'\n });\n }\n clean();\n // Permanently remove image from insertion batch.\n doc.enqueueChanges(() => {\n doc.batch('transparent').remove(imageElement);\n });\n });\n function clean() {\n doc.enqueueChanges(() => {\n doc.batch('transparent').removeAttribute(imageElement, 'uploadId');\n doc.batch('transparent').removeAttribute(imageElement, 'uploadStatus');\n });\n fileRepository.destroyLoader(loader);\n }\n }\n}\n// Returns true if non-empty `text/html` is included in data transfer.\n//\n// @param {module:clipboard/datatransfer~DataTransfer} dataTransfer\n// @returns {Boolean}\nexport function isHtmlIncluded(dataTransfer) {\n return Array.from(dataTransfer.types).includes('text/html') && dataTransfer.getData('text/html') !== '';\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/imageuploadengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module upload/ui/filedialogbuttonview\n */\n\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport View from '@ckeditor/ckeditor5-ui/src/view';\n\n/**\n * The file dialog button view.\n *\n * This component provides a button that opens the native file selection dialog.\n * It can be used to implement the UI of a file upload feature.\n *\n *\t\tconst view = new FileDialogButtonView( locale );\n *\n *\t\tview.set( {\n *\t\t\tacceptedType: 'image/*',\n *\t\t\tallowMultipleFiles: true\n *\t\t} );\n *\n *\t\tview.buttonView.set( {\n *\t\t\tlabel: t( 'Insert image' ),\n *\t\t\ticon: imageIcon,\n *\t\t\ttooltip: true\n *\t\t} );\n *\n *\t\tview.on( 'done', ( evt, files ) => {\n *\t\t\tfor ( const file of Array.from( files ) ) {\n *\t\t\t\tconsole.log( 'Selected file', file );\n *\t\t\t}\n *\t\t} );\n *\n * @extends module:ui/view~View\n */\nexport default class FileDialogButtonView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The button view of the component.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.buttonView = new ButtonView( locale );\n\n\t\t/**\n\t\t * A hidden `<input>` view used to execute file dialog.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:upload/ui/filedialogbuttonview~FileInputView}\n\t\t */\n\t\tthis._fileInputView = new FileInputView( locale );\n\n\t\t/**\n\t\t * Accepted file types. Can be provided in form of file extensions, media type or one of:\n\t\t * * `audio/*`,\n\t\t * * `video/*`,\n\t\t * * `image/*`.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #acceptedType\n\t\t */\n\t\tthis._fileInputView.bind( 'acceptedType' ).to( this );\n\n\t\t/**\n\t\t * Indicates if multiple files can be selected. Defaults to `true`.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #allowMultipleFiles\n\t\t */\n\t\tthis._fileInputView.bind( 'allowMultipleFiles' ).to( this );\n\n\t\t/**\n\t\t * Fired when file dialog is closed with file selected.\n\t\t *\n\t\t *\t\tview.on( 'done', ( evt, files ) => {\n\t\t *\t\t\tfor ( const file of files ) {\n\t\t *\t\t\t\tconsole.log( 'Selected file', file );\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t * @event done\n\t\t * @param {Array.<File>} files Array of selected files.\n\t\t */\n\t\tthis._fileInputView.delegate( 'done' ).to( this );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-file-dialog-button',\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis.buttonView,\n\t\t\t\tthis._fileInputView\n\t\t\t]\n\t\t} );\n\n\t\tthis.buttonView.on( 'execute', () => {\n\t\t\tthis._fileInputView.open();\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the {@link #buttonView}.\n\t */\n\tfocus() {\n\t\tthis.buttonView.focus();\n\t}\n}\n\n/**\n * The hidden file input view class.\n *\n * @private\n * @extends {module:ui/view~View}\n */\nclass FileInputView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * Accepted file types. Can be provided in form of file extensions, media type or one of:\n\t\t * * `audio/*`,\n\t\t * * `video/*`,\n\t\t * * `image/*`.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #acceptedType\n\t\t */\n\t\tthis.set( 'acceptedType' );\n\n\t\t/**\n\t\t * Indicates if multiple files can be selected. Defaults to `false`.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #allowMultipleFiles\n\t\t */\n\t\tthis.set( 'allowMultipleFiles', false );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'input',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-hidden'\n\t\t\t\t],\n\t\t\t\ttype: 'file',\n\t\t\t\ttabindex: '-1',\n\t\t\t\taccept: bind.to( 'acceptedType' ),\n\t\t\t\tmultiple: bind.to( 'allowMultipleFiles' )\n\t\t\t},\n\n\t\t\ton: {\n\t\t\t\t// Removing from code coverage since we cannot programmatically set input element files.\n\t\t\t\tchange: bind.to( /* istanbul ignore next */ () => {\n\t\t\t\t\tif ( this.element && this.element.files && this.element.files.length ) {\n\t\t\t\t\t\tthis.fire( 'done', this.element.files );\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.element.value = '';\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Opens file dialog.\n\t */\n\topen() {\n\t\tthis.element.click();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/ui/filedialogbuttonview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module upload/imageuploadprogress\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport { eventNameToConsumableType } from '@ckeditor/ckeditor5-engine/src/conversion/model-to-view-converters';\nimport FileRepository from './filerepository';\nimport uploadingPlaceholder from '../theme/icons/image_placeholder.svg';\nimport UIElement from '@ckeditor/ckeditor5-engine/src/view/uielement';\nimport ImageUploadEngine from './imageuploadengine';\n\nimport '../theme/imageuploadprogress.scss';\n\n/**\n * Image upload progress plugin.\n * Shows placeholder when image is read from disk and progress bar while image is uploading.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadProgress extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageUploadEngine ];\n\t}\n\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Image's placeholder that is displayed before real image data can be accessed.\n\t\t *\n\t\t * @protected\n\t\t * @member {String} #placeholder\n\t\t */\n\t\tthis.placeholder = 'data:image/svg+xml;utf8,' + encodeURIComponent( uploadingPlaceholder );\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Upload status change - update image's view according to that status.\n\t\teditor.editing.modelToView.on( 'addAttribute:uploadStatus:image', ( ...args ) => this.uploadStatusChange( ...args ) );\n\t\teditor.editing.modelToView.on( 'changeAttribute:uploadStatus:image', ( ...args ) => this.uploadStatusChange( ...args ) );\n\t}\n\n\t/**\n\t * This ethod is called each time image's `uploadStatus` attribute is changed.\n\t *\n\t * @param {module:utils/eventinfo~EventInfo} evt Object containing information about the fired event.\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t */\n\tuploadStatusChange( evt, data, consumable ) {\n\t\tconst editor = this.editor;\n\t\tconst modelImage = data.item;\n\t\tconst uploadId = modelImage.getAttribute( 'uploadId' );\n\n\t\tif ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) || !uploadId ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst placeholder = this.placeholder;\n\t\tconst status = data.attributeNewValue;\n\t\tconst viewFigure = editor.editing.mapper.toViewElement( modelImage );\n\n\t\t// Show placeholder with infinite progress bar on the top while image is read from disk.\n\t\tif ( status == 'reading' ) {\n\t\t\tviewFigure.addClass( 'ck-appear', 'ck-infinite-progress', 'ck-image-upload-placeholder' );\n\t\t\tconst viewImg = viewFigure.getChild( 0 );\n\t\t\tviewImg.setAttribute( 'src', placeholder );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Show progress bar on the top of the image when image is uploading.\n\t\tif ( status == 'uploading' ) {\n\t\t\tconst loader = fileRepository.loaders.get( uploadId );\n\n\t\t\tif ( loader ) {\n\t\t\t\tconst progressBar = createProgressBar();\n\n\t\t\t\tviewFigure.removeClass( 'ck-infinite-progress', 'ck-image-upload-placeholder' );\n\t\t\t\tviewFigure.appendChildren( progressBar );\n\n\t\t\t\t// Update progress bar width when uploadedPercent is changed.\n\t\t\t\tloader.on( 'change:uploadedPercent', ( evt, name, value ) => {\n\t\t\t\t\tprogressBar.setStyle( 'width', value + '%' );\n\t\t\t\t\teditor.editing.view.render();\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Hide progress bar and clean up classes.\n\t\tconst progressBar = getProgressBar( viewFigure );\n\n\t\tif ( progressBar ) {\n\t\t\tprogressBar.remove();\n\t\t} else {\n\t\t\tviewFigure.removeClass( 'ck-infinite-progress' );\n\t\t}\n\n\t\tviewFigure.removeClass( 'ck-appear', 'ck-image-upload-placeholder' );\n\t}\n}\n\n// Symbol added to progress bar UIElement to distinguish it from other elements.\nconst progressBarSymbol = Symbol( 'progress-bar' );\n\n// Create progress bar element using {@link module:engine/view/uielement~UIElement}.\n//\n// @private\n// @returns {module:engine/view/uielement~UIElement}\nfunction createProgressBar() {\n\tconst progressBar = new UIElement( 'div', { class: 'ck-progress-bar' } );\n\tprogressBar.setCustomProperty( progressBarSymbol, true );\n\n\treturn progressBar;\n}\n\n// Returns progress bar {@link module:engine/view/uielement~UIElement} from image figure element. Returns `undefined` if\n// progress bar element is not found.\n//\n// @private\n// @param {module:engine/view/element~Element} imageFigure\n// @returns {module:engine/view/uielement~UIElement|undefined}\nfunction getProgressBar( imageFigure ) {\n\tfor ( const child of imageFigure.getChildren() ) {\n\t\tif ( child.getCustomProperty( progressBarSymbol ) ) {\n\t\t\treturn child;\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/imageuploadprogress.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module upload/imageupload\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageUploadButton from './imageuploadbutton';\nimport ImageUploadProgress from './imageuploadprogress';\n\n/**\n * Image upload plugin.\n * This plugin do not do anything directly, but loads set of specific plugins to enable image uploading:\n * * {@link module:upload/imageuploadbutton~ImageUploadButton},\n * * {@link module:upload/imageuploadprogress~ImageUploadProgress}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUpload extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageUpload';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageUploadButton, ImageUploadProgress ];\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/imageupload.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module paragraph/paragraphcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport Position from '@ckeditor/ckeditor5-engine/src/model/position';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The paragraph command.\n *\n * @extends module:core/command~Command\n */\nexport default class ParagraphCommand extends Command {\n\t/**\n\t * The value of the command. Indicates whether the selection start is placed in a paragraph.\n\t *\n\t * @readonly\n\t * @observable\n\t * @member {Boolean} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst document = this.editor.document;\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tthis.value = !!block && block.is( 'paragraph' );\n\t\tthis.isEnabled = !!block && checkCanBecomeParagraph( block, document.schema );\n\t}\n\n\t/**\n\t * Executes the command. All the blocks (see {@link module:engine/model/schema~Schema}) in the selection\n\t * will be turned to paragraphs.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Options for the executed command.\n\t * @param {module:engine/model/batch~Batch} [options.batch] A batch to collect all the change steps.\n\t * A new batch will be created if this option is not set.\n\t * @param {module:engine/model/selection~Selection} [options.selection] The selection that the command should be applied to.\n\t * By default, if not provided, the command is applied to the {@link module:engine/model/document~Document#selection}.\n\t */\n\texecute( options = {} ) {\n\t\tconst document = this.editor.document;\n\n\t\tdocument.enqueueChanges( () => {\n\t\t\tconst batch = options.batch || document.batch();\n\t\t\tconst blocks = ( options.selection || document.selection ).getSelectedBlocks();\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tif ( !block.is( 'paragraph' ) && checkCanBecomeParagraph( block, document.schema ) ) {\n\t\t\t\t\tbatch.rename( block, 'paragraph' );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n// Checks whether the given block can be replaced by a paragraph.\n//\n// @private\n// @param {module:engine/model/element~Element} block A block to be tested.\n// @param {module:engine/model/schema~Schema} schema The schema of the document.\n// @returns {Boolean}\nfunction checkCanBecomeParagraph( block, schema ) {\n\treturn schema.check( {\n\t\tname: 'paragraph',\n\t\tinside: Position.createBefore( block )\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-paragraph/src/paragraphcommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module paragraph/paragraph\n */\n\nimport ParagraphCommand from './paragraphcommand';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';\nimport ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';\n\nimport buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';\nimport buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';\n\n/**\n * The paragraph feature for the editor.\n * It introduces the `<paragraph>` element in the model which renders as a `<p>` element in the DOM and data.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Paragraph extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Paragraph';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst doc = editor.document;\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\teditor.commands.add( 'paragraph', new ParagraphCommand( editor ) );\n\n\t\t// Schema.\n\t\tdoc.schema.registerItem( 'paragraph', '$block' );\n\n\t\t// Build converter from model to view for data and editing pipelines.\n\t\tbuildModelConverter().for( data.modelToView, editing.modelToView )\n\t\t\t.fromElement( 'paragraph' )\n\t\t\t.toElement( 'p' );\n\n\t\t// Build converter from view to model for data pipeline.\n\t\tbuildViewConverter().for( data.viewToModel )\n\t\t\t.fromElement( 'p' )\n\t\t\t.toElement( 'paragraph' );\n\n\t\t// Content autoparagraphing. --------------------------------------------------\n\n\t\t// Step 1.\n\t\t// \"Second chance\" converters for elements and texts which were not allowed in their original locations.\n\t\t// They check if this element/text could be converted if it was in a paragraph.\n\t\t// Forcefully converted items will be temporarily in an invalid context. It's going to be fixed in step 2.\n\n\t\t// Executed after converter added by a feature, but before \"default\" to-model-fragment converter.\n\t\tdata.viewToModel.on( 'element', convertAutoparagraphableItem, { priority: 'low' } );\n\t\t// Executed after default text converter.\n\t\tdata.viewToModel.on( 'text', convertAutoparagraphableItem, { priority: 'lowest' } );\n\n\t\t// Step 2.\n\t\t// After an item is \"forced\" to be converted by `convertAutoparagraphableItem`, we need to actually take\n\t\t// care of adding the paragraph (assumed in `convertAutoparagraphableItem`) and wrap that item in it.\n\n\t\t// Executed after all converters (even default ones).\n\t\tdata.viewToModel.on( 'element', autoparagraphItems, { priority: 'lowest' } );\n\t\tdata.viewToModel.on( 'documentFragment', autoparagraphItems, { priority: 'lowest' } );\n\n\t\t// Empty roots autoparagraphing. -----------------------------------------------\n\n\t\t// Post-fixer which takes care of adding empty paragraph elements to empty roots.\n\t\t// Besides fixing content on #changesDone we also need to handle #dataReady because\n\t\t// if initial data is empty or setData() wasn't even called there will be no #change fired.\n\t\tdoc.on( 'change', ( evt, type, changes, batch ) => {\n\t\t\tif ( batch.type == 'transparent' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfindEmptyRoots( doc, batch );\n\t\t} );\n\t\tdoc.on( 'changesDone', autoparagraphEmptyRoots, { priority: 'lowest' } );\n\t\teditor.on( 'dataReady', () => {\n\t\t\tfindEmptyRoots( doc, doc.batch( 'transparent' ) );\n\t\t\tautoparagraphEmptyRoots();\n\t\t}, { priority: 'lowest' } );\n\t}\n}\n\n/**\n * A list of element names which should be treated by the autoparagraphing algorithms as\n * paragraph-like. This means that e.g. the following content:\n *\n *\t\t<h1>Foo</h1>\n *\t\t<table>\n *\t\t\t<tr>\n *\t\t\t\t<td>X</td>\n *\t\t\t\t<td>\n *\t\t\t\t\t<ul>\n *\t\t\t\t\t\t<li>Y</li>\n *\t\t\t\t\t\t<li>Z</li>\n *\t\t\t\t\t</ul>\n *\t\t\t\t</td>\n *\t\t\t</tr>\n *\t\t</table>\n *\n * contains five paragraph-like elements: `<h1>`, two `<td>`s and two `<li>`s.\n * Hence, if none of the features is going to convert those elements the above content will be automatically handled\n * by the paragraph feature and converted to:\n *\n *\t\t<p>Foo</p>\n *\t\t<p>X</p>\n *\t\t<p>Y</p>\n *\t\t<p>Z</p>\n *\n * Note: The `<td>` containing two `<li>` elements was ignored as the innermost paragraph-like elements\n * have a priority upon conversion.\n *\n * @member {Set.<String>} module:paragraph/paragraph~Paragraph.paragraphLikeElements\n */\nParagraph.paragraphLikeElements = new Set( [\n\t'blockquote',\n\t'dd',\n\t'div',\n\t'dt',\n\t'h1',\n\t'h2',\n\t'h3',\n\t'h4',\n\t'h5',\n\t'h6',\n\t'li',\n\t'p',\n\t'td'\n] );\n\n// This converter forces a conversion of a non-consumed view item, if that item would be allowed by schema and converted it if was\n// inside a paragraph element. The converter checks whether conversion would be possible if there was a paragraph element\n// between `data.input` item and its parent. If the conversion would be allowed, the converter adds `\"paragraph\"` to the\n// context and fires conversion for `data.input` again.\nfunction convertAutoparagraphableItem( evt, data, consumable, conversionApi ) {\n\t// If the item wasn't consumed by some of the dedicated converters...\n\tif ( !consumable.test( data.input, { name: data.input.name } ) ) {\n\t\treturn;\n\t}\n\n\t// But would be allowed if it was in a paragraph...\n\tif ( !isParagraphable( data.input, data.context, conversionApi.schema, false ) ) {\n\t\treturn;\n\t}\n\n\t// Convert that item in a paragraph context.\n\tdata.context.push( 'paragraph' );\n\tconst item = conversionApi.convertItem( data.input, consumable, data );\n\tdata.context.pop();\n\n\tdata.output = item;\n}\n\n// This converter checks all children of an element or document fragment that has been converted and wraps\n// children in a paragraph element if it is allowed by schema.\n//\n// Basically, after an item is \"forced\" to be converted by `convertAutoparagraphableItem`, we need to actually take\n// care of adding the paragraph (assumed in `convertAutoparagraphableItem`) and wrap that item in it.\nfunction autoparagraphItems( evt, data, consumable, conversionApi ) {\n\t// Autoparagraph only if the element has been converted.\n\tif ( !data.output ) {\n\t\treturn;\n\t}\n\n\tconst isParagraphLike = Paragraph.paragraphLikeElements.has( data.input.name ) && !data.output.is( 'element' );\n\n\t// Keep in mind that this converter is added to all elements and document fragments.\n\t// This means that we have to make a smart decision in which elements (at what level) auto-paragraph should be inserted.\n\t// There are three situations when it is correct to add paragraph:\n\t// -\twe are converting a view document fragment: this means that we are at the top level of conversion and we should\n\t//\t\tadd paragraph elements for \"bare\" texts (unless converting in $clipboardHolder, but this is covered by schema),\n\t// -\twe are converting an element that was converted to model element: this means that it will be represented in model\n\t//\t\tand has added its context when converting children - we should add paragraph for those items that passed\n\t//\t\tin `convertAutoparagraphableItem`, because it is correct for them to be autoparagraphed,\n\t//\t -\twe are converting \"paragraph-like\" element, which children should always be autoparagraphed (if it is allowed by schema,\n\t//\t\tso we won't end up with, i.e., paragraph inside paragraph, if paragraph was in paragraph-like element).\n\tconst shouldAutoparagraph =\n\t\t( data.input.is( 'documentFragment' ) ) ||\n\t\t( data.input.is( 'element' ) && data.output.is( 'element' ) ) ||\n\t\tisParagraphLike;\n\n\tif ( !shouldAutoparagraph ) {\n\t\treturn;\n\t}\n\n\t// Take care of proper context. This is important for `isParagraphable` checks.\n\tconst needsNewContext = data.output.is( 'element' );\n\n\tif ( needsNewContext ) {\n\t\tdata.context.push( data.output );\n\t}\n\n\t// `paragraph` element that will wrap auto-paragraphable children.\n\tlet autoParagraph = null;\n\n\t// Check children and wrap them in a `paragraph` element if they need to be wrapped.\n\t// Be smart when wrapping children and put all auto-paragraphable siblings in one `paragraph` parent:\n\t// foo<$text bold=\"true\">bar</$text><paragraph>xxx</paragraph>baz --->\n\t// <paragraph>foo<$text bold=\"true\">bar</$text></paragraph><paragraph>xxx</paragraph><paragraph>baz</paragraph>\n\tfor ( let i = 0; i < data.output.childCount; i++ ) {\n\t\tconst child = data.output.getChild( i );\n\n\t\tif ( isParagraphable( child, data.context, conversionApi.schema, isParagraphLike ) ) {\n\t\t\t// If there is no wrapping `paragraph` element, create it.\n\t\t\tif ( !autoParagraph ) {\n\t\t\t\tautoParagraph = new ModelElement( 'paragraph' );\n\t\t\t\tdata.output.insertChildren( child.index, autoParagraph );\n\t\t\t}\n\t\t\t// Otherwise, use existing `paragraph` and just fix iterator.\n\t\t\t// Thanks to reusing `paragraph` element, multiple siblings ends up in same container.\n\t\t\telse {\n\t\t\t\ti--;\n\t\t\t}\n\n\t\t\tchild.remove();\n\t\t\tautoParagraph.appendChildren( child );\n\t\t} else {\n\t\t\t// That was not a paragraphable children, reset `paragraph` wrapper - following auto-paragraphable children\n\t\t\t// need to be placed in a new `paragraph` element.\n\t\t\tautoParagraph = null;\n\t\t}\n\t}\n\n\tif ( needsNewContext ) {\n\t\tdata.context.pop();\n\t}\n}\n\nfunction isParagraphable( node, context, schema, insideParagraphLikeElement ) {\n\tconst name = node.name || '$text';\n\n\t// Node is paragraphable if it is inside paragraph like element, or...\n\t// It is not allowed at this context...\n\tif ( !insideParagraphLikeElement && schema.check( { name, inside: context } ) ) {\n\t\treturn false;\n\t}\n\n\t// And paragraph is allowed in this context...\n\tif ( !schema.check( { name: 'paragraph', inside: context } ) ) {\n\t\treturn false;\n\t}\n\n\t// And a node would be allowed in this paragraph...\n\tif ( !schema.check( { name, inside: context.concat( 'paragraph' ) } ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n// Looks through all roots created in document and marks every empty root, saving which batch made it empty.\nconst rootsToFix = new Map();\n\nfunction findEmptyRoots( doc, batch ) {\n\tfor ( const rootName of doc.getRootNames() ) {\n\t\tconst root = doc.getRoot( rootName );\n\n\t\tif ( root.isEmpty ) {\n\t\t\tif ( !rootsToFix.has( root ) ) {\n\t\t\t\trootsToFix.set( root, batch );\n\t\t\t}\n\t\t} else {\n\t\t\trootsToFix.delete( root );\n\t\t}\n\t}\n}\n\n// Fixes all empty roots.\nfunction autoparagraphEmptyRoots() {\n\tfor ( const [ root, batch ] of rootsToFix ) {\n\t\t// Only empty roots are in `rootsToFix`. Even if root got content during `changesDone` event (because of, for example\n\t\t// other feature), this will fire `findEmptyRoots` and remove that root from `rootsToFix`. So we are guaranteed\n\t\t// to have only empty roots here.\n\t\tconst query = { name: 'paragraph', inside: [ root ] };\n\t\tconst doc = batch.document;\n\t\tconst schema = doc.schema;\n\n\t\t// If paragraph element is allowed in the root, create paragraph element.\n\t\tif ( schema.check( query ) ) {\n\t\t\tdoc.enqueueChanges( () => {\n\t\t\t\t// Remove root from `rootsToFix` here, before executing batch, to prevent infinite loops.\n\t\t\t\trootsToFix.delete( root );\n\n\t\t\t\t// Fix empty root.\n\t\t\t\tbatch.insert( ModelPosition.createAt( root ), new ModelElement( 'paragraph' ) );\n\t\t\t} );\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-paragraph/src/paragraph.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module heading/headingcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport Position from '@ckeditor/ckeditor5-engine/src/model/position';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The heading command. It is used by the {@link module:heading/heading~Heading heading feature} to apply headings.\n *\n * @extends module:core/command~Command\n */\nexport default class HeadingCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor instance.\n\t * @param {String} modelElement Name of the element which this command will apply in the model.\n\t */\n\tconstructor( editor, modelElement ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Whether the selection starts in a heading of {@link #modelElement this level}.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\n\t\t/**\n\t\t * Unique identifier of the command, also element's name in the model.\n\t\t * See {@link module:heading/heading~HeadingOption}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.modelElement = modelElement;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst block = first( this.editor.document.selection.getSelectedBlocks() );\n\n\t\tthis.value = !!block && block.is( this.modelElement );\n\t\tthis.isEnabled = !!block && checkCanBecomeHeading( block, this.modelElement, this.editor.document.schema );\n\t}\n\n\t/**\n\t * Executes the command. Applies the heading to the selected blocks or, if the first selected\n\t * block is a heading already, turns selected headings (of this level only) to paragraphs.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Options for executed command.\n\t * @param {module:engine/model/batch~Batch} [options.batch] Batch to collect all the change steps.\n\t * New batch will be created if this option is not set.\n\t */\n\texecute( options = {} ) {\n\t\tconst editor = this.editor;\n\t\tconst document = editor.document;\n\n\t\tdocument.enqueueChanges( () => {\n\t\t\tconst batch = options.batch || document.batch();\n\t\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t\t.filter( block => {\n\t\t\t\t\treturn checkCanBecomeHeading( block, this.modelElement, document.schema );\n\t\t\t\t} );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tif ( !block.is( this.modelElement ) ) {\n\t\t\t\t\tbatch.rename( block, this.modelElement );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n// Checks whether the given block can be replaced by a specific heading.\n//\n// @private\n// @param {module:engine/model/element~Element} block A block to be tested.\n// @param {module:heading/headingcommand~HeadingCommand#modelElement} heading Command element name in the model.\n// @param {module:engine/model/schema~Schema} schema The schema of the document.\n// @returns {Boolean}\nfunction checkCanBecomeHeading( block, heading, schema ) {\n\treturn schema.check( {\n\t\tname: heading,\n\t\tinside: Position.createBefore( block )\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-heading/src/headingcommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module heading/headingengine\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';\nimport buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';\nimport Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';\nimport HeadingCommand from './headingcommand';\n\nconst defaultModelElement = 'paragraph';\n\n/**\n * The headings engine feature. It handles switching between block formats &ndash; headings and paragraph.\n * This class represents the engine part of the heading feature. See also {@link module:heading/heading~Heading}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class HeadingEngine extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'heading', {\n\t\t\toptions: [\n\t\t\t\t{ modelElement: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },\n\t\t\t\t{ modelElement: 'heading1', viewElement: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },\n\t\t\t\t{ modelElement: 'heading2', viewElement: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },\n\t\t\t\t{ modelElement: 'heading3', viewElement: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Paragraph ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\t\tconst options = editor.config.get( 'heading.options' );\n\n\t\tfor ( const option of options ) {\n\t\t\t// Skip paragraph - it is defined in required Paragraph feature.\n\t\t\tif ( option.modelElement !== defaultModelElement ) {\n\t\t\t\t// Schema.\n\t\t\t\teditor.document.schema.registerItem( option.modelElement, '$block' );\n\n\t\t\t\t// Build converter from model to view for data and editing pipelines.\n\t\t\t\tbuildModelConverter().for( data.modelToView, editing.modelToView )\n\t\t\t\t\t.fromElement( option.modelElement )\n\t\t\t\t\t.toElement( option.viewElement );\n\n\t\t\t\t// Build converter from view to model for data pipeline.\n\t\t\t\tbuildViewConverter().for( data.viewToModel )\n\t\t\t\t\t.fromElement( option.viewElement )\n\t\t\t\t\t.toElement( option.modelElement );\n\n\t\t\t\t// Register the heading command for this option.\n\t\t\t\teditor.commands.add( option.modelElement, new HeadingCommand( editor, option.modelElement ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\t// If the enter command is added to the editor, alter its behavior.\n\t\t// Enter at the end of a heading element should create a paragraph.\n\t\tconst editor = this.editor;\n\t\tconst enterCommand = editor.commands.get( 'enter' );\n\t\tconst options = editor.config.get( 'heading.options' );\n\n\t\tif ( enterCommand ) {\n\t\t\tthis.listenTo( enterCommand, 'afterExecute', ( evt, data ) => {\n\t\t\t\tconst positionParent = editor.document.selection.getFirstPosition().parent;\n\t\t\t\tconst batch = data.batch;\n\t\t\t\tconst isHeading = options.some( option => positionParent.is( option.modelElement ) );\n\n\t\t\t\tif ( isHeading && !positionParent.is( defaultModelElement ) && positionParent.childCount === 0 ) {\n\t\t\t\t\tbatch.rename( positionParent, defaultModelElement );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-heading/src/headingengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/dropdown/createdropdown\n */\n\nimport ButtonView from '../button/buttonview';\nimport DropdownView from './dropdownview';\nimport DropdownPanelView from './dropdownpanelview';\n\n/**\n * A helper which creates an instance of {@link module:ui/dropdown/dropdownview~DropdownView} class using\n * a provided {@link module:ui/dropdown/dropdownmodel~DropdownModel}.\n *\n *\t\tconst model = new Model( {\n *\t\t\tlabel: 'A dropdown',\n *\t\t\tisEnabled: true,\n *\t\t\tisOn: false,\n *\t\t\twithText: true\n *\t\t} );\n *\n *\t\tconst dropdown = createDropdown( model );\n *\n *\t\tdropdown.render();\n *\n *\t\t// Will render a dropdown labeled \"A dropdown\" with an empty panel.\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * The model instance remains in control of the dropdown after it has been created. E.g. changes to the\n * {@link module:ui/dropdown/dropdownmodel~DropdownModel#label `model.label`} will be reflected in the\n * dropdown button's {@link module:ui/button/buttonview~ButtonView#label} attribute and in DOM.\n *\n * Also see {@link module:ui/dropdown/list/createlistdropdown~createListDropdown}.\n *\n * @param {module:ui/dropdown/dropdownmodel~DropdownModel} model Model of this dropdown.\n * @param {module:utils/locale~Locale} locale The locale instance.\n * @returns {module:ui/dropdown/dropdownview~DropdownView} The dropdown view instance.\n */\nexport default function createDropdown( model, locale ) {\n\tconst buttonView = new ButtonView( locale );\n\tbuttonView.bind( 'label', 'isOn', 'isEnabled', 'withText', 'keystroke', 'tooltip' ).to( model );\n\n\tconst panelView = new DropdownPanelView( locale );\n\n\treturn new DropdownView( locale, buttonView, panelView );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/dropdown/createdropdown.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/dropdown/list/createlistdropdown\n */\n\n/* global document */\n\nimport ListView from '../../list/listview';\nimport ListItemView from '../../list/listitemview';\nimport createDropdown from '../createdropdown';\n\n/**\n * Creates an instance of {@link module:ui/dropdown/list/listdropdownview~ListDropdownView} class using\n * a provided {@link module:ui/dropdown/list/listdropdownmodel~ListDropdownModel}.\n *\n *\t\tconst items = new Collection();\n *\n *\t\titems.add( new Model( { label: 'First item', style: 'color: red' } ) );\n *\t\titems.add( new Model( { label: 'Second item', style: 'color: green', class: 'foo' } ) );\n *\n *\t\tconst model = new Model( {\n *\t\t\tisEnabled: true,\n *\t\t\titems,\n *\t\t\tisOn: false,\n *\t\t\tlabel: 'A dropdown'\n *\t\t} );\n *\n *\t\tconst dropdown = createListDropdown( model, locale );\n *\n *\t\t// Will render a dropdown labeled \"A dropdown\" with a list in the panel\n *\t\t// containing two items.\n *\t\tdropdown.render()\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * The model instance remains in control of the dropdown after it has been created. E.g. changes to the\n * {@link module:ui/dropdown/dropdownmodel~DropdownModel#label `model.label`} will be reflected in the\n * dropdown button's {@link module:ui/button/buttonview~ButtonView#label} attribute and in DOM.\n *\n * The\n * {@link module:ui/dropdown/list/listdropdownmodel~ListDropdownModel#items items collection}\n * of the {@link module:ui/dropdown/list/listdropdownmodel~ListDropdownModel model} also controls the\n * presence and attributes of respective {@link module:ui/list/listitemview~ListItemView list items}.\n *\n * See {@link module:ui/dropdown/createdropdown~createDropdown} and {@link module:list/list~List}.\n *\n * @param {module:ui/dropdown/list/listdropdownmodel~ListDropdownModel} model Model of the list dropdown.\n * @param {module:utils/locale~Locale} locale The locale instance.\n * @returns {module:ui/dropdown/list/listdropdownview~ListDropdownView} The list dropdown view instance.\n */\nexport default function createListDropdown( model, locale ) {\n\tconst dropdownView = createDropdown( model, locale );\n\tconst listView = dropdownView.listView = new ListView( locale );\n\n\tlistView.items.bindTo( model.items ).using( itemModel => {\n\t\tconst item = new ListItemView( locale );\n\n\t\t// Bind all attributes of the model to the item view.\n\t\titem.bind( ...Object.keys( itemModel ) ).to( itemModel );\n\n\t\treturn item;\n\t} );\n\n\t// TODO: Delegate all events instead of just execute.\n\tlistView.items.delegate( 'execute' ).to( dropdownView );\n\n\tdropdownView.panelView.children.add( listView );\n\n\tdropdownView.on( 'change:isOpen', ( evt, name, value ) => {\n\t\tif ( value ) {\n\t\t\tattachDocumentClickListener( dropdownView );\n\t\t} else {\n\t\t\tdropdownView.stopListening( document );\n\t\t}\n\t} );\n\n\t// Close the dropdown when one of the list items has been executed.\n\tdropdownView.on( 'execute', () => {\n\t\tdropdownView.isOpen = false;\n\t} );\n\n\t// If the dropdown panel is already open, the arrow down key should\n\t// focus the first element in list.\n\tdropdownView.keystrokes.set( 'arrowdown', ( data, cancel ) => {\n\t\tif ( dropdownView.isOpen ) {\n\t\t\tlistView.focus();\n\t\t\tcancel();\n\t\t}\n\t} );\n\n\t// If the dropdown panel is already open, the arrow up key should\n\t// focus the last element in the list.\n\tdropdownView.keystrokes.set( 'arrowup', ( data, cancel ) => {\n\t\tif ( dropdownView.isOpen ) {\n\t\t\tlistView.focusLast();\n\t\t\tcancel();\n\t\t}\n\t} );\n\n\treturn dropdownView;\n}\n\n// Attaches a \"click\" listener in DOM to check if any element outside\n// the dropdown has been clicked.\n//\n// @private\n// @param {module:ui/dropdown/listdropdownview~ListDropdownView} dropdownView\nfunction attachDocumentClickListener( dropdownView ) {\n\t// TODO: It will probably be focus/blur-based rather than click. It should be bound\n\t// to focusmanager of some sort.\n\tdropdownView.listenTo( document, 'click', ( evtInfo, { target: domEvtTarget } ) => {\n\t\t// Collapse the dropdown when the webpage outside of the component is clicked.\n\t\tif ( dropdownView.element != domEvtTarget && !dropdownView.element.contains( domEvtTarget ) ) {\n\t\t\tdropdownView.isOpen = false;\n\t\t}\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/dropdown/list/createlistdropdown.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module heading/heading\n */\nimport Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';\nimport HeadingEngine from './headingengine';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Model from '@ckeditor/ckeditor5-ui/src/model';\nimport createListDropdown from '@ckeditor/ckeditor5-ui/src/dropdown/list/createlistdropdown';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport '../theme/theme.scss';\n/**\n * The headings feature. It introduces the `headings` drop-down and the `heading1`-`headingN` commands which allow\n * to convert paragraphs into headings.\n *\n * For a detailed overview, check the {@glink features/headings Headings feature documentation}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Heading extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [\n Paragraph,\n HeadingEngine\n ];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'Heading';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const dropdownItems = new Collection();\n const options = this._getLocalizedOptions();\n const commands = [];\n const t = editor.t;\n const defaultTitle = t('Choose heading');\n const dropdownTooltip = t('Heading');\n for (const option of options) {\n const command = editor.commands.get(option.modelElement);\n const itemModel = new Model({\n commandName: option.modelElement,\n label: option.title,\n class: option.class\n });\n itemModel.bind('isActive').to(command, 'value');\n // Add the option to the collection.\n dropdownItems.add(itemModel);\n commands.push(command);\n }\n // Create dropdown model.\n const dropdownModel = new Model({\n withText: true,\n items: dropdownItems,\n tooltip: dropdownTooltip\n });\n dropdownModel.bind('isEnabled').to(// Bind to #isEnabled of each command...\n ...getCommandsBindingTargets(commands, 'isEnabled'), // ...and set it true if any command #isEnabled is true.\n (...areEnabled) => areEnabled.some(isEnabled => isEnabled));\n dropdownModel.bind('label').to(// Bind to #value of each command...\n ...getCommandsBindingTargets(commands, 'value'), // ...and chose the title of the first one which #value is true.\n (...areActive) => {\n const index = areActive.findIndex(value => value);\n // If none of the commands is active, display default title.\n return options[index] ? options[index].title : defaultTitle;\n });\n // Register UI component.\n editor.ui.componentFactory.add('headings', locale => {\n const dropdown = createListDropdown(dropdownModel, locale);\n dropdown.extendTemplate({ attributes: { class: ['ck-heading-dropdown'] } });\n // Execute command when an item from the dropdown is selected.\n this.listenTo(dropdown, 'execute', evt => {\n editor.execute(evt.source.commandName);\n editor.editing.view.focus();\n });\n return dropdown;\n });\n }\n /**\n\t * Returns heading options as defined in `config.heading.options` but processed to consider\n\t * editor localization, i.e. to display {@link module:heading/heading~HeadingOption}\n\t * in the correct language.\n\t *\n\t * Note: The reason behind this method is that there's no way to use {@link module:utils/locale~Locale#t}\n\t * when the user config is defined because the editor does not exist yet.\n\t *\n\t * @private\n\t * @returns {Array.<module:heading/heading~HeadingOption>}.\n\t */\n _getLocalizedOptions() {\n const editor = this.editor;\n const t = editor.t;\n const localizedTitles = {\n Paragraph: t('Paragraph'),\n 'Heading 1': t('Heading 1'),\n 'Heading 2': t('Heading 2'),\n 'Heading 3': t('Heading 3')\n };\n return editor.config.get('heading.options').map(option => {\n const title = localizedTitles[option.title];\n if (title && title != option.title) {\n // Clone the option to avoid altering the original `config.heading.options`.\n option = Object.assign({}, option, { title });\n }\n return option;\n });\n }\n}\n// Returns an array of binding components for\n// {@link module:utils/observablemixin~Observable#bind} from a set of iterable\n// commands.\n//\n// @private\n// @param {Iterable.<module:core/command~Command>} commands\n// @param {String} attribute\n// @returns {Array.<String>}\nfunction getCommandsBindingTargets(commands, attribute) {\n return Array.prototype.concat(...commands.map(c => [\n c,\n attribute\n ]));\n} /**\n * Heading option descriptor.\n *\n * @typedef {Object} module:heading/heading~HeadingOption\n * @property {String} modelElement Element's name in the model.\n * @property {String} viewElement The name of the view element that will be used to represent the model element in the view.\n * @property {String} title The user-readable title of the option.\n * @property {String} class The class which will be added to the dropdown item representing this option.\n */\n /**\n * The configuration of the heading feature. Introduced by the {@link module:heading/headingengine~HeadingEngine} feature.\n *\n * Read more in {@link module:heading/heading~HeadingConfig}.\n *\n * @member {module:heading/heading~HeadingConfig} module:core/editor/editorconfig~EditorConfig#heading\n */\n /**\n * The configuration of the heading feature.\n * The option is used by the {@link module:heading/headingengine~HeadingEngine} feature.\n *\n *\t\tClassicEditor\n *\t\t\t.create( {\n * \t\t\t\theading: ... // Heading feature config.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface HeadingConfig\n */\n /**\n * The available heading options.\n *\n * The default value is:\n *\n *\t\tconst headingConfig = {\n *\t\t\toptions: [\n *\t\t\t\t{ modelElement: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },\n *\t\t\t\t{ modelElement: 'heading1', viewElement: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },\n *\t\t\t\t{ modelElement: 'heading2', viewElement: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },\n *\t\t\t\t{ modelElement: 'heading3', viewElement: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }\n *\t\t\t]\n *\t\t};\n *\n * It defines 3 levels of headings. In the editor model they will use `heading1`, `heading2`, and `heading3` elements.\n * Their respective view elements (so the elements output by the editor) will be: `h2`, `h3`, and `h4`. This means that\n * if you choose \"Heading 1\" in the headings dropdown the editor will turn the current block to `<heading1>` in the model\n * which will result in rendering (and outputting to data) the `<h2>` element.\n *\n * The `title` and `class` properties will be used by the `headings` dropdown to render available options.\n * Usually, the first option in the headings dropdown is the \"Paragraph\" option, hence it's also defined on the list.\n * However, you don't need to define its view representation because it's handled by\n * the {@link module:paragraph/paragraph~Paragraph} feature (which is required by\n * the {@link module:heading/headingengine~HeadingEngine} feature).\n *\n * Note: In the model you should always start from `heading1`, regardless of how the headings are represented in the view.\n * That's assumption is used by features like {@link module:autoformat/autoformat~Autoformat} to know which element\n * they should use when applying the first level heading.\n *\n * The defined headings are also available in {@link module:core/commandcollection~CommandCollection} under their model names.\n * For example, the below code will apply `<heading1>` to the current selection:\n *\n *\t\teditor.execute( 'heading1' );\n *\n * @member {Array.<module:heading/heading~HeadingOption>} module:heading/heading~HeadingConfig#options\n */\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-heading/src/heading.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/placeholder\n */\n\nimport extend from '@ckeditor/ckeditor5-utils/src/lib/lodash/extend';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport '../../theme/placeholder.scss';\n\nconst listener = {};\nextend( listener, EmitterMixin );\n\n// Each document stores information about its placeholder elements and check functions.\nconst documentPlaceholders = new WeakMap();\n\n/**\n * Attaches placeholder to provided element and updates it's visibility. To change placeholder simply call this method\n * once again with new parameters.\n *\n * @param {module:engine/view/element~Element} element Element to attach placeholder to.\n * @param {String} placeholderText Placeholder text to use.\n * @param {Function} [checkFunction] If provided it will be called before checking if placeholder should be displayed.\n * If function returns `false` placeholder will not be showed.\n */\nexport function attachPlaceholder( element, placeholderText, checkFunction ) {\n\tconst document = element.document;\n\n\tif ( !document ) {\n\t\t/**\n\t\t * Provided element is not placed in any {@link module:engine/view/document~Document}.\n\t\t *\n\t\t * @error view-placeholder-element-is-detached\n\t\t */\n\t\tthrow new CKEditorError( 'view-placeholder-element-is-detached: Provided element is not placed in document.' );\n\t}\n\n\t// Detach placeholder if was used before.\n\tdetachPlaceholder( element );\n\n\t// Single listener per document.\n\tif ( !documentPlaceholders.has( document ) ) {\n\t\tdocumentPlaceholders.set( document, new Map() );\n\t\tlistener.listenTo( document, 'render', () => updateAllPlaceholders( document ), { priority: 'high' } );\n\t}\n\n\t// Store text in element's data attribute.\n\t// This data attribute is used in CSS class to show the placeholder.\n\telement.setAttribute( 'data-placeholder', placeholderText );\n\n\t// Store information about placeholder.\n\tdocumentPlaceholders.get( document ).set( element, checkFunction );\n\n\t// Update right away too.\n\tupdateSinglePlaceholder( element, checkFunction );\n}\n\n/**\n * Removes placeholder functionality from given element.\n *\n * @param {module:engine/view/element~Element} element\n */\nexport function detachPlaceholder( element ) {\n\tconst document = element.document;\n\n\telement.removeClass( 'ck-placeholder' );\n\telement.removeAttribute( 'data-placeholder' );\n\n\tif ( documentPlaceholders.has( document ) ) {\n\t\tdocumentPlaceholders.get( document ).delete( element );\n\t}\n}\n\n// Updates all placeholders of given document.\n//\n// @private\n// @param {module:engine/view/document~Document} document\nfunction updateAllPlaceholders( document ) {\n\tconst placeholders = documentPlaceholders.get( document );\n\n\tfor ( const [ element, checkFunction ] of placeholders ) {\n\t\tupdateSinglePlaceholder( element, checkFunction );\n\t}\n}\n\n// Updates placeholder class of given element.\n//\n// @private\n// @param {module:engine/view/element~Element} element\n// @param {Function} checkFunction\nfunction updateSinglePlaceholder( element, checkFunction ) {\n\tconst document = element.document;\n\n\t// Element was removed from document.\n\tif ( !document ) {\n\t\treturn;\n\t}\n\n\tconst viewSelection = document.selection;\n\tconst anchor = viewSelection.anchor;\n\n\t// If checkFunction is provided and returns false - remove placeholder.\n\tif ( checkFunction && !checkFunction() ) {\n\t\telement.removeClass( 'ck-placeholder' );\n\n\t\treturn;\n\t}\n\n\t// Element is empty for placeholder purposes when it has no children or only ui elements.\n\t// This check is taken from `view.ContainerElement#getFillerOffset`.\n\tconst isEmptyish = !Array.from( element.getChildren() ).some( element => !element.is( 'uiElement' ) );\n\n\t// If element is empty and editor is blurred.\n\tif ( !document.isFocused && isEmptyish ) {\n\t\telement.addClass( 'ck-placeholder' );\n\n\t\treturn;\n\t}\n\n\t// It there are no child elements and selection is not placed inside element.\n\tif ( isEmptyish && anchor && anchor.parent !== element ) {\n\t\telement.addClass( 'ck-placeholder' );\n\t} else {\n\t\telement.removeClass( 'ck-placeholder' );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/placeholder.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagecaption/utils\n */\n\nimport ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';\nimport ViewEditableElement from '@ckeditor/ckeditor5-engine/src/view/editableelement';\nimport { attachPlaceholder } from '@ckeditor/ckeditor5-engine/src/view/placeholder';\nimport { toWidgetEditable } from '@ckeditor/ckeditor5-widget/src/utils';\n\nconst captionSymbol = Symbol( 'imageCaption' );\n\n/**\n * Returns a function that creates a caption editable element for the given {@link module:engine/view/document~Document}.\n *\n * @param {module:engine/view/document~Document} viewDocument\n * @param {String} placeholderText The text to be displayed when the caption is empty.\n * @return {Function}\n */\nexport function captionElementCreator( viewDocument, placeholderText ) {\n\treturn () => {\n\t\tconst editable = new ViewEditableElement( 'figcaption' );\n\t\teditable.document = viewDocument;\n\t\teditable.setCustomProperty( captionSymbol, true );\n\t\tattachPlaceholder( editable, placeholderText );\n\n\t\treturn toWidgetEditable( editable );\n\t};\n}\n\n/**\n * Returns `true` if a given view element is the image caption editable.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @return {Boolean}\n */\nexport function isCaption( viewElement ) {\n\treturn !!viewElement.getCustomProperty( captionSymbol );\n}\n\n/**\n * Returns the caption model element from a given image element. Returns `null` if no caption is found.\n *\n * @param {module:engine/model/element~Element} imageModelElement\n * @return {module:engine/model/element~Element|null}\n */\nexport function getCaptionFromImage( imageModelElement ) {\n\tfor ( const node of imageModelElement.getChildren() ) {\n\t\tif ( node instanceof ModelElement && node.name == 'caption' ) {\n\t\t\treturn node;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a `<figcaption>` element that is placed\n * inside the image `<figure>` element.\n *\n * @param {module:engine/view/element~Element} element\n * @returns {Object|null} Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element\n * cannot be matched.\n */\nexport function matchImageCaption( element ) {\n\tconst parent = element.parent;\n\n\t// Convert only captions for images.\n\tif ( element.name == 'figcaption' && parent && parent.name == 'figure' && parent.hasClass( 'image' ) ) {\n\t\treturn { name: true };\n\t}\n\n\treturn null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagecaption/utils.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imagecaption/imagecaptionengine\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ModelTreeWalker from '@ckeditor/ckeditor5-engine/src/model/treewalker';\nimport ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';\nimport ViewContainerElement from '@ckeditor/ckeditor5-engine/src/view/containerelement';\nimport ViewElement from '@ckeditor/ckeditor5-engine/src/view/element';\nimport viewWriter from '@ckeditor/ckeditor5-engine/src/view/writer';\nimport ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';\nimport ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\nimport buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';\nimport { isImage } from '../image/utils';\nimport {\n captionElementCreator,\n getCaptionFromImage,\n matchImageCaption\n} from './utils';\n/**\n * The image caption engine plugin.\n *\n * It registers proper converters. It takes care of adding a caption element if the image without it is inserted\n * to the model document.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageCaptionEngine extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const document = editor.document;\n const viewDocument = editor.editing.view;\n const schema = document.schema;\n const data = editor.data;\n const editing = editor.editing;\n const t = editor.t;\n /**\n\t\t * Last selected caption editable.\n\t\t * It is used for hiding the editable when it is empty and the image widget is no longer selected.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/editableelement~EditableElement} #_lastSelectedCaption\n\t\t */\n /**\n\t\t * A function used to create the editable caption element in the editing view.\n\t\t *\n\t\t * @private\n\t\t * @member {Function}\n\t\t */\n this._createCaption = captionElementCreator(viewDocument, t('Enter image caption'));\n // Schema configuration.\n schema.registerItem('caption', '$block');\n schema.allow({\n name: '$inline',\n inside: 'caption'\n });\n schema.allow({\n name: 'caption',\n inside: 'image'\n });\n schema.limits.add('caption');\n // Add caption element to each image inserted without it.\n document.on('change', insertMissingModelCaptionElement);\n // View to model converter for the data pipeline.\n buildViewConverter().for(data.viewToModel).from(matchImageCaption).toElement('caption');\n // Model to view converter for the data pipeline.\n data.modelToView.on('insert:caption', captionModelToView(new ViewContainerElement('figcaption'), false));\n // Model to view converter for the editing pipeline.\n editing.modelToView.on('insert:caption', captionModelToView(this._createCaption));\n // Always show caption in view when something is inserted in model.\n editing.modelToView.on('insert', (evt, data) => this._fixCaptionVisibility(data.item), { priority: 'high' });\n // Hide caption when everything is removed from it.\n editing.modelToView.on('remove', (evt, data) => this._fixCaptionVisibility(data.sourcePosition.parent), { priority: 'high' });\n // Update view before each rendering.\n this.listenTo(viewDocument, 'render', () => this._updateCaptionVisibility(), { priority: 'high' });\n }\n /**\n\t * Updates the view before each rendering, making sure that empty captions (so unnecessary ones) are hidden\n\t * and then visible when the image is selected.\n\t *\n\t * @private\n\t */\n _updateCaptionVisibility() {\n const mapper = this.editor.editing.mapper;\n let viewCaption;\n // Hide last selected caption if have no child elements.\n if (this._lastSelectedCaption && !this._lastSelectedCaption.childCount) {\n this._lastSelectedCaption.addClass('ck-hidden');\n }\n // If whole image is selected.\n const modelSelection = this.editor.document.selection;\n const selectedElement = modelSelection.getSelectedElement();\n if (selectedElement && selectedElement.is('image')) {\n const modelCaption = getCaptionFromImage(selectedElement);\n viewCaption = mapper.toViewElement(modelCaption);\n }\n // If selection is placed inside caption.\n const position = modelSelection.getFirstPosition();\n const modelCaption = getParentCaption(position.parent);\n if (modelCaption) {\n viewCaption = mapper.toViewElement(modelCaption);\n }\n if (viewCaption) {\n viewCaption.removeClass('ck-hidden');\n this._lastSelectedCaption = viewCaption;\n }\n }\n /**\n\t * Fixes caption visibility during the model-to-view conversion.\n\t * Checks if the changed node is placed inside the caption element and fixes its visibility in the view.\n\t *\n\t * @private\n\t * @param {module:engine/model/node~Node} node\n\t */\n _fixCaptionVisibility(node) {\n const modelCaption = getParentCaption(node);\n const mapper = this.editor.editing.mapper;\n if (modelCaption) {\n const viewCaption = mapper.toViewElement(modelCaption);\n if (viewCaption) {\n if (modelCaption.childCount) {\n viewCaption.removeClass('ck-hidden');\n } else {\n viewCaption.addClass('ck-hidden');\n }\n }\n }\n }\n}\n// Checks whether data inserted to the model document have image element that has no caption element inside it.\n// If there is none - adds it to the image element.\n//\n// @private\nfunction insertMissingModelCaptionElement(evt, changeType, data, batch) {\n if (changeType !== 'insert') {\n return;\n }\n const walker = new ModelTreeWalker({\n boundaries: data.range,\n ignoreElementEnd: true\n });\n for (const value of walker) {\n const item = value.item;\n if (value.type == 'elementStart' && isImage(item) && !getCaptionFromImage(item)) {\n batch.document.enqueueChanges(() => {\n // Make sure that the image does not have caption already.\n // https://github.com/ckeditor/ckeditor5-image/issues/78\n if (!getCaptionFromImage(item)) {\n batch.insert(ModelPosition.createAt(item, 'end'), new ModelElement('caption'));\n }\n });\n }\n }\n}\n// Creates a converter that converts image caption model element to view element.\n//\n// @private\n// @param {Function|module:engine/view/element~Element} elementCreator\n// @param {Boolean} [hide=true] When set to `false` view element will not be inserted when it's empty.\n// @return {Function}\nfunction captionModelToView(elementCreator, hide = true) {\n return (evt, data, consumable, conversionApi) => {\n const captionElement = data.item;\n // Return if element shouldn't be present when empty.\n if (!captionElement.childCount && !hide) {\n return;\n }\n if (isImage(captionElement.parent)) {\n if (!consumable.consume(data.item, 'insert')) {\n return;\n }\n const viewImage = conversionApi.mapper.toViewElement(data.range.start.parent);\n const viewCaption = elementCreator instanceof ViewElement ? elementCreator.clone(true) : elementCreator();\n // Hide if empty.\n if (!captionElement.childCount) {\n viewCaption.addClass('ck-hidden');\n }\n insertViewCaptionAndBind(viewCaption, data.item, viewImage, conversionApi.mapper);\n }\n };\n}\n// Inserts `viewCaption` at the end of `viewImage` and binds it to `modelCaption`.\n//\n// @private\n// @param {module:engine/view/containerelement~ContainerElement} viewCaption\n// @param {module:engine/model/element~Element} modelCaption\n// @param {module:engine/view/containerelement~ContainerElement} viewImage\n// @param {module:engine/conversion/mapper~Mapper} mapper\nfunction insertViewCaptionAndBind(viewCaption, modelCaption, viewImage, mapper) {\n const viewPosition = ViewPosition.createAt(viewImage, 'end');\n viewWriter.insert(viewPosition, viewCaption);\n mapper.bindElements(modelCaption, viewCaption);\n}\n/**\n * Checks if the provided node or one of its ancestors is a caption element, and returns it.\n *\n * @param {module:engine/model/node~Node} node\n * @returns {module:engine/model/element~Element|null}\n */\nfunction getParentCaption(node) {\n const ancestors = node.getAncestors({ includeSelf: true });\n const caption = ancestors.find(ancestor => ancestor.name == 'caption');\n if (caption && caption.parent && caption.parent.name == 'image') {\n return caption;\n }\n return null;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagecaption/imagecaptionengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagestyle/converters\n */\n\nimport { isImage } from '../image/utils';\n\n/**\n * Returns a converter for the `imageStyle` attribute. It can be used for adding, changing and removing the attribute.\n *\n * @param {Object} styles An object containing available styles. See {@link module:image/imagestyle/imagestyleengine~ImageStyleFormat}\n * for more details.\n * @returns {Function} A model-to-view attribute converter.\n */\nexport function modelToViewStyleAttribute( styles ) {\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tconst eventType = evt.name.split( ':' )[ 0 ];\n\t\tconst consumableType = eventType + ':imageStyle';\n\n\t\tif ( !consumable.test( data.item, consumableType ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if there is class name associated with given value.\n\t\tconst newStyle = getStyleByName( data.attributeNewValue, styles );\n\t\tconst oldStyle = getStyleByName( data.attributeOldValue, styles );\n\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item );\n\n\t\tconst isRemovalHandled = handleRemoval( eventType, oldStyle, viewElement );\n\t\tconst isAdditionHandled = handleAddition( eventType, newStyle, viewElement );\n\n\t\t// https://github.com/ckeditor/ckeditor5-image/issues/132\n\t\tif ( isRemovalHandled || isAdditionHandled ) {\n\t\t\tconsumable.consume( data.item, consumableType );\n\t\t}\n\t};\n}\n\n/**\n * Returns a view-to-model converter converting image CSS classes to a proper value in the model.\n *\n * @param {Array.<module:image/imagestyle/imagestyleengine~ImageStyleFormat>} styles Styles for which the converter is created.\n * @returns {Function} A view-to-model converter.\n */\nexport function viewToModelStyleAttribute( styles ) {\n\t// Convert only nondefault styles.\n\tconst filteredStyles = styles.filter( style => !style.isDefault );\n\n\treturn ( evt, data, consumable, conversionApi ) => {\n\t\tfor ( const style of filteredStyles ) {\n\t\t\tviewToModelImageStyle( style, data, consumable, conversionApi );\n\t\t}\n\t};\n}\n\n// Converter from view to model converting single style.\n// For more information see {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher};\n//\n// @param {module:image/imagestyle/imagestyleengine~ImageStyleFormat} style\n// @param {Object} data\n// @param {module:engine/conversion/viewconsumable~ViewConsumable} consumable\n// @param {Object} conversionApi\nfunction viewToModelImageStyle( style, data, consumable, conversionApi ) {\n\tconst viewFigureElement = data.input;\n\tconst modelImageElement = data.output;\n\n\t// *** Step 1: Validate conversion.\n\t// Check if view element has proper class to consume.\n\tif ( !consumable.test( viewFigureElement, { class: style.className } ) ) {\n\t\treturn;\n\t}\n\n\t// Check if figure is converted to image.\n\tif ( !isImage( modelImageElement ) ) {\n\t\treturn;\n\t}\n\n\t// Check if image element can be placed in current context wit additional attribute.\n\tconst attributes = [ ...modelImageElement.getAttributeKeys(), 'imageStyle' ];\n\n\tif ( !conversionApi.schema.check( { name: 'image', inside: data.context, attributes } ) ) {\n\t\treturn;\n\t}\n\n\t// *** Step2: Convert to model.\n\tconsumable.consume( viewFigureElement, { class: style.className } );\n\tmodelImageElement.setAttribute( 'imageStyle', style.name );\n}\n\n// Returns style with given `name` from array of styles.\n//\n// @param {String} name\n// @param {Array.<module:image/imagestyle/imagestyleengine~ImageStyleFormat> } styles\n// @return {module:image/imagestyle/imagestyleengine~ImageStyleFormat|undefined}\nfunction getStyleByName( name, styles ) {\n\tfor ( const style of styles ) {\n\t\tif ( style.name === name ) {\n\t\t\treturn style;\n\t\t}\n\t}\n}\n\n// Handles converting removal of the attribute.\n// Returns `true` when handling was processed correctly and further conversion can be performed.\n//\n// @param {String} eventType Type of the event.\n// @param {module:image/imagestyle/imagestyleengine~ImageStyleFormat} style\n// @param {module:engine/view/element~Element} viewElement\n// @returns {Boolean} Whether the change was handled.\nfunction handleRemoval( eventType, style, viewElement ) {\n\tif ( style && ( eventType == 'changeAttribute' || eventType == 'removeAttribute' ) ) {\n\t\tviewElement.removeClass( style.className );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n// Handles converting addition of the attribute.\n// Returns `true` when handling was processed correctly and further conversion can be performed.\n//\n// @param {String} eventType Type of the event.\n// @param {module:image/imagestyle/imagestyleengine~ImageStyleFormat} style\n// @param {module:engine/view/element~Element} viewElement\n// @returns {Boolean} Whether the change was handled.\nfunction handleAddition( evenType, style, viewElement ) {\n\tif ( style && ( evenType == 'addAttribute' || evenType == 'changeAttribute' ) ) {\n\t\tviewElement.addClass( style.className );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagestyle/converters.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imagestyle/imagestyleengine\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageStyleCommand from './imagestylecommand';\nimport ImageEngine from '../image/imageengine';\nimport {\n viewToModelStyleAttribute,\n modelToViewStyleAttribute\n} from './converters';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport fullWidthIcon from '@ckeditor/ckeditor5-core/theme/icons/object-full-width.svg';\nimport leftIcon from '@ckeditor/ckeditor5-core/theme/icons/object-left.svg';\nimport centerIcon from '@ckeditor/ckeditor5-core/theme/icons/object-center.svg';\nimport rightIcon from '@ckeditor/ckeditor5-core/theme/icons/object-right.svg';\n/**\n * The image style engine plugin. It sets the default configuration, creates converters and registers\n * {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand ImageStyleCommand}.\n *\n * @extends {module:core/plugin~Plugin}\n */\nexport default class ImageStyleEngine extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [ImageEngine];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'ImageStyleEngine';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const doc = editor.document;\n const schema = doc.schema;\n const data = editor.data;\n const editing = editor.editing;\n // Define default configuration.\n editor.config.define('image.styles', [\n 'imageStyleFull',\n 'imageStyleSide'\n ]);\n // Get configuration.\n const styles = this.imageStyles;\n // Allow imageStyle attribute in image.\n // We could call it 'style' but https://github.com/ckeditor/ckeditor5-engine/issues/559.\n schema.allow({\n name: 'image',\n attributes: 'imageStyle',\n inside: '$root'\n });\n // Converters for imageStyle attribute from model to view.\n const modelToViewConverter = modelToViewStyleAttribute(styles);\n editing.modelToView.on('addAttribute:imageStyle:image', modelToViewConverter);\n data.modelToView.on('addAttribute:imageStyle:image', modelToViewConverter);\n editing.modelToView.on('changeAttribute:imageStyle:image', modelToViewConverter);\n data.modelToView.on('changeAttribute:imageStyle:image', modelToViewConverter);\n editing.modelToView.on('removeAttribute:imageStyle:image', modelToViewConverter);\n data.modelToView.on('removeAttribute:imageStyle:image', modelToViewConverter);\n // Converter for figure element from view to model.\n data.viewToModel.on('element:figure', viewToModelStyleAttribute(styles), { priority: 'low' });\n // Register separate command for each style.\n for (const style of styles) {\n editor.commands.add(style.name, new ImageStyleCommand(editor, style));\n }\n }\n /**\n\t * Returns {@link module:image/image~ImageConfig#styles} array with items normalized in the\n\t * {@link module:image/imagestyle/imagestyleengine~ImageStyleFormat} format, translated\n\t * `title` and a complete `icon` markup for each style.\n\t *\n\t * @readonly\n\t * @type {Array.<module:image/imagestyle/imagestyleengine~ImageStyleFormat>}\n\t */\n get imageStyles() {\n // Return cached value if there is one to improve the performance.\n if (this._cachedImageStyles) {\n return this._cachedImageStyles;\n }\n const styles = [];\n const editor = this.editor;\n const titles = this.localizedDefaultStylesTitles;\n const configuredStyles = editor.config.get('image.styles');\n for (let style of configuredStyles) {\n style = normalizeStyle(style);\n // Localize the titles of the styles, if a title corresponds with\n // a localized default provided by the plugin.\n if (titles[style.title]) {\n style.title = titles[style.title];\n }\n // Don't override the user-defined styles array, clone it instead.\n styles.push(style);\n }\n return this._cachedImageStyles = styles;\n }\n /**\n\t * Returns the default localized style titles provided by the plugin e.g. ready to\n\t * use in the {@link #imageStyles}.\n\t *\n\t * The following localized titles corresponding with\n\t * {@link module:image/imagestyle/imagestyleengine~ImageStyleEngine.defaultStyles} are available:\n\t *\n\t * * `'Full size image'`,\n\t * * `'Side image'`,\n\t * * `'Left aligned image'`,\n\t * * `'Centered image'`,\n\t * * `'Right aligned image'`\n\t *\n\t * @readonly\n\t * @type {Object.<String,String>}\n\t */\n get localizedDefaultStylesTitles() {\n const t = this.editor.t;\n return {\n 'Full size image': t('Full size image'),\n 'Side image': t('Side image'),\n 'Left aligned image': t('Left aligned image'),\n 'Centered image': t('Centered image'),\n 'Right aligned image': t('Right aligned image')\n };\n }\n}\n/**\n * Default image styles provided by the plugin, which can be referred in the\n * {@link module:image/image~ImageConfig#styles} config.\n *\n * Among them, 2 default semantic content styles are available:\n *\n * * `imageStyleFull` is a fullwidth image without any CSS class,\n * * `imageStyleSide` is a side image styled with the `image-style-side` CSS class\n *\n * There are also 3 styles focused on formatting:\n *\n * * `imageStyleAlignLeft` aligns the image to the left using the `image-style-align-left` class,\n * * `imageStyleAlignCenter` centers the image to the left using the `image-style-align-center` class,\n * * `imageStyleAlignRight` aligns the image to the right using the `image-style-align-right` class,\n *\n * @member {Object.<String,Object>}\n */\nImageStyleEngine.defaultStyles = {\n // This option is equal to situation when no style is applied.\n imageStyleFull: {\n name: 'imageStyleFull',\n title: 'Full size image',\n icon: fullWidthIcon,\n isDefault: true\n },\n // This represents side image.\n imageStyleSide: {\n name: 'imageStyleSide',\n title: 'Side image',\n icon: rightIcon,\n className: 'image-style-side'\n },\n // This style represents an imaged aligned to the left.\n imageStyleAlignLeft: {\n name: 'imageStyleAlignLeft',\n title: 'Left aligned image',\n icon: leftIcon,\n className: 'image-style-align-left'\n },\n // This style represents a centered imaged.\n imageStyleAlignCenter: {\n name: 'imageStyleAlignCenter',\n title: 'Centered image',\n icon: centerIcon,\n className: 'image-style-align-center'\n },\n // This style represents an imaged aligned to the right.\n imageStyleAlignRight: {\n name: 'imageStyleAlignRight',\n title: 'Right aligned image',\n icon: rightIcon,\n className: 'image-style-align-right'\n }\n};\n/**\n * Default image style icons provided by the plugin, which can be referred in the\n * {@link module:image/image~ImageConfig#styles} config.\n *\n * There are 4 icons available: `'full'`, `'left'`, `'center'` and `'right'`.\n *\n * @member {Object.<String, String>}\n */\nImageStyleEngine.defaultIcons = {\n full: fullWidthIcon,\n left: leftIcon,\n right: rightIcon,\n center: centerIcon\n};\n// Normalizes an image style provided in the {@link module:image/image~ImageConfig#styles}\n// and returns it in a {@link module:image/imagestyle/imagestyleengine~ImageStyleFormat}.\n//\n// @private\n// @param {Object} style\n// @returns {@link module:image/imagestyle/imagestyleengine~ImageStyleFormat}\nfunction normalizeStyle(style) {\n const defaultStyles = ImageStyleEngine.defaultStyles;\n const defaultIcons = ImageStyleEngine.defaultIcons;\n // Just the name of the style has been passed.\n if (typeof style == 'string') {\n // If it's one of the defaults, just use it.\n // Clone the style to avoid overriding defaults.\n if (defaultStyles[style]) {\n style = Object.assign({}, defaultStyles[style]);\n } // If it's just a name but none of the defaults, warn because probably it's a mistake.\n else {\n log.warn('image-style-not-found: There is no such image style of given name.', { name: style });\n // Normalize the style anyway to prevent errors.\n style = { name: style };\n }\n } // If an object style has been passed and if the name matches one of the defaults,\n // extend it with defaults the user wants to customize a default style.\n // Note: Don't override the userdefined style object, clone it instead.\n else if (defaultStyles[style.name]) {\n const defaultStyle = defaultStyles[style.name];\n const extendedStyle = Object.assign({}, style);\n for (const prop in defaultStyle) {\n if (!style.hasOwnProperty(prop)) {\n extendedStyle[prop] = defaultStyle[prop];\n }\n }\n style = extendedStyle;\n }\n // If an icon is defined as a string and correspond with a name\n // in default icons, use the default icon provided by the plugin.\n if (typeof style.icon == 'string' && defaultIcons[style.icon]) {\n style.icon = defaultIcons[style.icon];\n }\n return style;\n} /**\n * Image style format descriptor.\n *\n *\t\timport fullWidthIcon from 'path/to/icon.svg`;\n *\n *\t\tconst imageStyleFormat = {\n *\t\t\tname: 'fullSizeImage',\n *\t\t\ticon: fullWidthIcon,\n *\t\t\ttitle: 'Full size image',\n *\t\t\tclassName: 'image-full-size'\n *\t\t}\n *\n * @typedef {Object} module:image/imagestyle/imagestyleengine~ImageStyleFormat\n * @property {String} name The unique name of the style. It will be used to:\n * * register the {@link module:core/command~Command command} which will apply this style,\n * * store the style's button in the editor {@link module:ui/componentfactory~ComponentFactory},\n * * store the style in the `imageStyle` model attribute.\n * @property {Boolean} [isDefault] When set, the style will be used as the default one.\n * A default style does not apply any CSS class to the view element.\n * @property {String} icon One of the following to be used when creating the style's button:\n * * An SVG icon source (as an XML string),\n * * One of {@link module:image/imagestyle/imagestyleengine~ImageStyleEngine.defaultIcons} to use a default icon provided by the plugin.\n * @property {String} title The style's title.\n * @property {String} className The CSS class used to represent the style in view.\n */\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagestyle/imagestyleengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagestyle\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageStyleEngine from './imagestyle/imagestyleengine';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\n/**\n * The image style plugin.\n *\n * Uses the {@link module:image/imagestyle/imagestyleengine~ImageStyleEngine}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageStyle extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageStyleEngine ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageStyle';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst styles = editor.plugins.get( ImageStyleEngine ).imageStyles;\n\n\t\tfor ( const style of styles ) {\n\t\t\tthis._createButton( style );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a button for each style and stores it in the editor {@link module:ui/componentfactory~ComponentFactory ComponentFactory}.\n\t *\n\t * @private\n\t * @param {module:image/imagestyle/imagestyleengine~ImageStyleFormat} style\n\t */\n\t_createButton( style ) {\n\t\tconst editor = this.editor;\n\t\tconst command = editor.commands.get( style.name );\n\n\t\teditor.ui.componentFactory.add( style.name, locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: style.title,\n\t\t\t\ticon: style.icon,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t\t\tview.bind( 'isOn' ).to( command, 'value' );\n\n\t\t\tthis.listenTo( view, 'execute', () => editor.execute( style.name ) );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n}\n\n/**\n * Available image styles.\n * The option is used by the {@link module:image/imagestyle/imagestyleengine~ImageStyleEngine} feature.\n *\n * The default value is:\n *\n * \t\tconst imageConfig = {\n *\t\t\tstyles: [ 'imageStyleFull', 'imageStyleSide' ]\n *\t\t};\n *\n * which configures two default styles:\n *\n * * the \"full\" style which doesn't apply any class, e.g. for images styled to span 100% width of the content,\n * * the \"side\" style with the `.image-style-side` CSS class.\n *\n * See {@link module:image/imagestyle/imagestyleengine~ImageStyleEngine.defaultStyles} to learn more about default\n * styles provided by the image feature.\n *\n * The {@link module:image/imagestyle/imagestyleengine~ImageStyleEngine.defaultStyles default styles} can be customized,\n * e.g. to change the icon, title or CSS class of the style. The feature also provides several\n * {@link module:image/imagestyle/imagestyleengine~ImageStyleEngine.defaultIcons default icons} to chose from.\n *\n *\t\timport customIcon from 'custom-icon.svg';\n *\n *\t\t// ...\n *\n *\t\tconst imageConfig = {\n *\t\t\tstyles: [\n *\t\t\t\t// This will only customize the icon of the \"full\" style.\n *\t\t\t\t// Note: 'right' is one of default icons provided by the feature.\n *\t\t\t\t{ name: 'imageStyleFull', icon: 'right' },\n *\n *\t\t\t\t// This will customize the icon, title and CSS class of the default \"side\" style.\n *\t\t\t\t{ name: 'imageStyleSide', icon: customIcon, title: 'My side style', class: 'custom-side-image' }\n *\t\t\t]\n *\t\t};\n *\n * If none of the default styles is good enough, it is possible to define independent custom styles too:\n *\n *\t\timport fullSizeIcon from '@ckeditor/ckeditor5-core/theme/icons/object-center.svg';\n *\t\timport sideIcon from '@ckeditor/ckeditor5-core/theme/icons/object-right.svg';\n *\n *\t\t// ...\n *\n *\t\tconst imageConfig = {\n *\t\t\tstyles: [\n *\t\t\t\t// A completely custom full size style with no class, used as a default.\n *\t\t\t\t{ name: 'fullSize', title: 'Full size', icon: fullSizeIcon, isDefault: true },\n *\n *\t\t\t\t{ name: 'side', title: 'To the side', icon: sideIcon, className: 'side-image' }\n *\t\t\t]\n *\t\t};\n *\n * Note: Setting `title` to one of {@link module:image/imagestyle/imagestyleengine~ImageStyleEngine#localizedDefaultStylesTitles}\n * will automatically translate it to the language of the editor.\n *\n * Read more about styling images in the {@glink features/image#Image-styles Image styles guide}.\n *\n * The feature creates commands based on defined styles, so you can change the style of a selected image by executing\n * the following command:\n *\n *\t\teditor.execute( 'imageStyleSide' );\n *\n * The features creates also buttons which execute the commands, so assuming that you use the\n * default image styles setting you can {@link module:image/image~ImageConfig#toolbar configure the image toolbar}\n * to contain these options:\n *\n *\t\tconst imageConfig = {\n *\t\t\ttoolbar: [ 'imageStyleFull', 'imageStyleSide' ]\n *\t\t};\n *\n * @member {Array.<module:image/imagestyle/imagestyleengine~ImageStyleFormat>} module:image/image~ImageConfig#styles\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagestyle.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/findlinkrange\n */\n\nimport Range from '@ckeditor/ckeditor5-engine/src/model/range';\nimport Position from '@ckeditor/ckeditor5-engine/src/model/position';\n\n/**\n * Walks backward and forward from the start position, node by node, as long as they have the same `linkHref` attribute value and return\n * a {@link module:engine/model/range~Range Range} with the found link.\n *\n * @param {module:engine/model/position~Position} position The start position.\n * @param {String} value The `linkHref` attribute value.\n * @returns {module:engine/model/range~Range} The link range.\n */\nexport default function findLinkRange( position, value ) {\n\treturn new Range( _findBound( position, value, true ), _findBound( position, value, false ) );\n}\n\n// Walks forward or backward (depends on the `lookBack` flag), node by node, as long as they have the same `linkHref` attribute value\n// and returns a position just before or after (depends on the `lookBack` flag) the last matched node.\n//\n// @param {module:engine/model/position~Position} position The start position.\n// @param {String} value The `linkHref` attribute value.\n// @param {Boolean} lookBack Whether the walk direction is forward (`false`) or backward (`true`).\n// @returns {module:engine/model/position~Position} The position just before the last matched node.\nfunction _findBound( position, value, lookBack ) {\n\t// Get node before or after position (depends on `lookBack` flag).\n\t// When position is inside text node then start searching from text node.\n\tlet node = position.textNode || ( lookBack ? position.nodeBefore : position.nodeAfter );\n\n\tlet lastNode = null;\n\n\twhile ( node && node.getAttribute( 'linkHref' ) == value ) {\n\t\tlastNode = node;\n\t\tnode = lookBack ? node.previousSibling : node.nextSibling;\n\t}\n\n\treturn lastNode ? Position.createAt( lastNode, lookBack ? 'before' : 'after' ) : position;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/src/findlinkrange.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/linkcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport Text from '@ckeditor/ckeditor5-engine/src/model/text';\nimport Range from '@ckeditor/ckeditor5-engine/src/model/range';\nimport findLinkRange from './findlinkrange';\n\n/**\n * The link command. It is used by the {@link module:link/link~Link link feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class LinkCommand extends Command {\n\t/**\n\t * The value of the `'linkHref'` attribute if the start of the selection is located in a node with this attribute.\n\t *\n\t * @observable\n\t * @readonly\n\t * @member {Object|undefined} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst doc = this.editor.document;\n\n\t\tthis.value = doc.selection.getAttribute( 'linkHref' );\n\t\tthis.isEnabled = doc.schema.checkAttributeInSelection( doc.selection, 'linkHref' );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is non-collapsed, the `linkHref` attribute will be applied to nodes inside the selection, but only to\n\t * those nodes where the `linkHref` attribute is allowed (disallowed nodes will be omitted).\n\t *\n\t * When the selection is collapsed and is not inside the text with the `linkHref` attribute, the\n\t * new {@link module:engine/model/text~Text Text node} with the `linkHref` attribute will be inserted in place of caret, but\n\t * only if such element is allowed in this place. The `_data` of the inserted text will equal the `href` parameter.\n\t * The selection will be updated to wrap the just inserted text node.\n\t *\n\t * When the selection is collapsed and inside the text with the `linkHref` attribute, the attribute value will be updated.\n\t *\n\t * @fires execute\n\t * @param {String} href Link destination.\n\t */\n\texecute( href ) {\n\t\tconst doc = this.editor.document;\n\t\tconst selection = doc.selection;\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\t// Keep it as one undo step.\n\t\t\tconst batch = doc.batch();\n\n\t\t\t// If selection is collapsed then update selected link or insert new one at the place of caret.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tconst position = selection.getFirstPosition();\n\n\t\t\t\t// When selection is inside text with `linkHref` attribute.\n\t\t\t\tif ( selection.hasAttribute( 'linkHref' ) ) {\n\t\t\t\t\t// Then update `linkHref` value.\n\t\t\t\t\tconst linkRange = findLinkRange( selection.getFirstPosition(), selection.getAttribute( 'linkHref' ) );\n\n\t\t\t\t\tbatch.setAttribute( linkRange, 'linkHref', href );\n\n\t\t\t\t\t// Create new range wrapping changed link.\n\t\t\t\t\tselection.setRanges( [ linkRange ] );\n\t\t\t\t}\n\t\t\t\t// If not then insert text node with `linkHref` attribute in place of caret.\n\t\t\t\telse {\n\t\t\t\t\tconst node = new Text( href, { linkHref: href } );\n\n\t\t\t\t\tbatch.insert( position, node );\n\n\t\t\t\t\t// Create new range wrapping created node.\n\t\t\t\t\tselection.setRanges( [ Range.createOn( node ) ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If selection has non-collapsed ranges, we change attribute on nodes inside those ranges\n\t\t\t\t// omitting nodes where `linkHref` attribute is disallowed.\n\t\t\t\tconst ranges = doc.schema.getValidRanges( selection.getRanges(), 'linkHref' );\n\n\t\t\t\tfor ( const range of ranges ) {\n\t\t\t\t\tbatch.setAttribute( range, 'linkHref', href );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/src/linkcommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module link/link\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ClickObserver from '@ckeditor/ckeditor5-engine/src/view/observer/clickobserver';\nimport Range from '@ckeditor/ckeditor5-engine/src/view/range';\nimport LinkEngine from './linkengine';\nimport LinkElement from './linkelement';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\nimport clickOutsideHandler from '@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport LinkFormView from './ui/linkformview';\nimport linkIcon from '../theme/icons/link.svg';\nimport '../theme/theme.scss';\nconst linkKeystroke = 'Ctrl+K';\n/**\n * The link plugin. It introduces the Link and Unlink buttons and the <kbd>Ctrl+K</kbd> keystroke.\n *\n * It uses the {@link module:link/linkengine~LinkEngine link engine plugin} and the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Link extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [\n LinkEngine,\n ContextualBalloon\n ];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'Link';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n editor.editing.view.addObserver(ClickObserver);\n /**\n\t\t * The form view displayed inside the balloon.\n\t\t *\n\t\t * @member {module:link/ui/linkformview~LinkFormView}\n\t\t */\n this.formView = this._createForm();\n /**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n this._balloon = editor.plugins.get(ContextualBalloon);\n // Create toolbar buttons.\n this._createToolbarLinkButton();\n // Attach lifecycle actions to the the balloon.\n this._attachActions();\n }\n /**\n\t * Creates the {@link module:link/ui/linkformview~LinkFormView} instance.\n\t *\n\t * @private\n\t * @returns {module:link/ui/linkformview~LinkFormView} The link form instance.\n\t */\n _createForm() {\n const editor = this.editor;\n const formView = new LinkFormView(editor.locale);\n const linkCommand = editor.commands.get('link');\n const unlinkCommand = editor.commands.get('unlink');\n formView.urlInputView.bind('value').to(linkCommand, 'value');\n // Form elements should be read-only when corresponding commands are disabled.\n formView.urlInputView.bind('isReadOnly').to(linkCommand, 'isEnabled', value => !value);\n formView.saveButtonView.bind('isEnabled').to(linkCommand);\n formView.unlinkButtonView.bind('isEnabled').to(unlinkCommand);\n // Execute link command after clicking on formView `Save` button.\n this.listenTo(formView, 'submit', () => {\n editor.execute('link', formView.urlInputView.inputView.element.value);\n this._hidePanel(true);\n });\n // Execute unlink command after clicking on formView `Unlink` button.\n this.listenTo(formView, 'unlink', () => {\n editor.execute('unlink');\n this._hidePanel(true);\n });\n // Hide the panel after clicking on formView `Cancel` button.\n this.listenTo(formView, 'cancel', () => this._hidePanel(true));\n // Close the panel on esc key press when the form has focus.\n formView.keystrokes.set('Esc', (data, cancel) => {\n this._hidePanel(true);\n cancel();\n });\n return formView;\n }\n /**\n\t * Creates a toolbar Link button. Clicking this button will show\n\t * a {@link #_balloon} attached to the selection.\n\t *\n\t * @private\n\t */\n _createToolbarLinkButton() {\n const editor = this.editor;\n const linkCommand = editor.commands.get('link');\n const t = editor.t;\n // Handle the `Ctrl+K` keystroke and show the panel.\n editor.keystrokes.set(linkKeystroke, (keyEvtData, cancel) => {\n // Prevent focusing the search bar in FF and opening new tab in Edge. #153, #154.\n cancel();\n if (linkCommand.isEnabled) {\n this._showPanel(true);\n }\n });\n editor.ui.componentFactory.add('link', locale => {\n const button = new ButtonView(locale);\n button.isEnabled = true;\n button.label = t('Link');\n button.icon = linkIcon;\n button.keystroke = linkKeystroke;\n button.tooltip = true;\n // Bind button to the command.\n button.bind('isEnabled').to(linkCommand, 'isEnabled');\n // Show the panel on button click.\n this.listenTo(button, 'execute', () => this._showPanel(true));\n return button;\n });\n }\n /**\n\t * Attaches actions that control whether the balloon panel containing the\n\t * {@link #formView} is visible or not.\n\t *\n\t * @private\n\t */\n _attachActions() {\n const viewDocument = this.editor.editing.view;\n // Handle click on view document and show panel when selection is placed inside the link element.\n // Keep panel open until selection will be inside the same link element.\n this.listenTo(viewDocument, 'click', () => {\n const parentLink = this._getSelectedLinkElement();\n if (parentLink) {\n // Then show panel but keep focus inside editor editable.\n this._showPanel();\n }\n });\n // Focus the form if the balloon is visible and the Tab key has been pressed.\n this.editor.keystrokes.set('Tab', (data, cancel) => {\n if (this._balloon.visibleView === this.formView && !this.formView.focusTracker.isFocused) {\n this.formView.focus();\n cancel();\n }\n }, {\n // Use the high priority because the link UI navigation is more important\n // than other feature's actions, e.g. list indentation.\n // https://github.com/ckeditor/ckeditor5-link/issues/146\n priority: 'high'\n });\n // Close the panel on the Esc key press when the editable has focus and the balloon is visible.\n this.editor.keystrokes.set('Esc', (data, cancel) => {\n if (this._balloon.visibleView === this.formView) {\n this._hidePanel();\n cancel();\n }\n });\n // Close on click outside of balloon panel element.\n clickOutsideHandler({\n emitter: this.formView,\n activator: () => this._balloon.hasView(this.formView),\n contextElements: [this._balloon.view.element],\n callback: () => this._hidePanel()\n });\n }\n /**\n\t * Adds the {@link #formView} to the {@link #_balloon}.\n\t *\n\t * @protected\n\t * @param {Boolean} [focusInput=false] When `true`, the link form will be focused on panel show.\n\t */\n _showPanel(focusInput) {\n const editor = this.editor;\n const linkCommand = editor.commands.get('link');\n const unlinkCommand = editor.commands.get('unlink');\n const editing = editor.editing;\n const showViewDocument = editing.view;\n const showIsCollapsed = showViewDocument.selection.isCollapsed;\n const showSelectedLink = this._getSelectedLinkElement();\n this.listenTo(showViewDocument, 'render', () => {\n const renderSelectedLink = this._getSelectedLinkElement();\n const renderIsCollapsed = showViewDocument.selection.isCollapsed;\n const hasSellectionExpanded = showIsCollapsed && !renderIsCollapsed;\n // Hide the panel if:\n // * the selection went out of the original link element\n // (e.g. paragraph containing the link was removed),\n // * the selection has expanded\n // upon the #render event.\n if (hasSellectionExpanded || showSelectedLink !== renderSelectedLink) {\n this._hidePanel(true);\n } // Update the position of the panel when:\n // * the selection remains in the original link element,\n // * there was no link element in the first place, i.e. creating a new link\n else {\n // If still in a link element, simply update the position of the balloon.\n // If there was no link, upon #render, the balloon must be moved\n // to the new position in the editing view (a new native DOM range).\n this._balloon.updatePosition(this._getBalloonPositionData());\n }\n });\n if (this._balloon.hasView(this.formView)) {\n // Check if formView should be focused and focus it if is visible.\n if (focusInput && this._balloon.visibleView === this.formView) {\n this.formView.urlInputView.select();\n }\n } else {\n this._balloon.add({\n view: this.formView,\n position: this._getBalloonPositionData()\n });\n if (focusInput) {\n this.formView.urlInputView.select();\n }\n }\n // https://github.com/ckeditor/ckeditor5-link/issues/53\n this.formView.unlinkButtonView.isVisible = unlinkCommand.isEnabled;\n // Make sure that each time the panel shows up, the URL field remains in sync with the value of\n // the command. If the user typed in the input, then canceled the balloon (`urlInputView#value` stays\n // unaltered) and re-opened it without changing the value of the link command (e.g. because they\n // clicked the same link), they would see the old value instead of the actual value of the command.\n // https://github.com/ckeditor/ckeditor5-link/issues/78\n // https://github.com/ckeditor/ckeditor5-link/issues/123\n this.formView.urlInputView.inputView.element.value = linkCommand.value || '';\n }\n /**\n\t * Removes the {@link #formView} from the {@link #_balloon}.\n\t *\n\t * See {@link #_showPanel}.\n\t *\n\t * @protected\n\t * @param {Boolean} [focusEditable=false] When `true`, editable focus will be restored on panel hide.\n\t */\n _hidePanel(focusEditable) {\n this.stopListening(this.editor.editing.view, 'render');\n if (!this._balloon.hasView(this.formView)) {\n return;\n }\n if (focusEditable) {\n this.editor.editing.view.focus();\n }\n this.stopListening(this.editor.editing.view, 'render');\n this._balloon.remove(this.formView);\n }\n /**\n\t * Returns positioning options for the {@link #_balloon}. They control the way the balloon is attached\n\t * to the target element or selection.\n\t *\n\t * If the selection is collapsed and inside a link element, the panel will be attached to the\n\t * entire link element. Otherwise, it will be attached to the selection.\n\t *\n\t * @private\n\t * @returns {module:utils/dom/position~Options}\n\t */\n _getBalloonPositionData() {\n const viewDocument = this.editor.editing.view;\n const targetLink = this._getSelectedLinkElement();\n const target = targetLink ? // When selection is inside link element, then attach panel to this element.\n viewDocument.domConverter.mapViewToDom(targetLink) : // Otherwise attach panel to the selection.\n viewDocument.domConverter.viewRangeToDom(viewDocument.selection.getFirstRange());\n return { target };\n }\n /**\n\t * Returns the {@link module:link/linkelement~LinkElement} under\n\t * the {@link module:engine/view/document~Document editing view's} selection or `null`\n\t * if there is none.\n\t *\n\t * **Note**: For a noncollapsed selection the `LinkElement` is only returned when **fully**\n\t * selected and the **only** element within the selection boundaries.\n\t *\n\t * @private\n\t * @returns {module:link/linkelement~LinkElement|null}\n\t */\n _getSelectedLinkElement() {\n const selection = this.editor.editing.view.selection;\n if (selection.isCollapsed) {\n return findLinkElementAncestor(selection.getFirstPosition());\n } else {\n // The range for fully selected link is usually anchored in adjacent text nodes.\n // Trim it to get closer to the actual LinkElement.\n const range = selection.getFirstRange().getTrimmed();\n const startLink = findLinkElementAncestor(range.start);\n const endLink = findLinkElementAncestor(range.end);\n if (!startLink || startLink != endLink) {\n return null;\n }\n // Check if the LinkElement is fully selected.\n if (Range.createIn(startLink).getTrimmed().isEqual(range)) {\n return startLink;\n } else {\n return null;\n }\n }\n }\n}\n// Returns a `LinkElement` if there's one among the ancestors of the provided `Position`.\n//\n// @private\n// @param {module:engine/view/position~Position} View position to analyze.\n// @returns {module:link/linkelement~LinkElement|null} LinkElement at the position or null.\nfunction findLinkElementAncestor(position) {\n return position.getAncestors().find(ancestor => ancestor instanceof LinkElement);\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/src/link.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/listcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport Position from '@ckeditor/ckeditor5-engine/src/model/position';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The list command. It is used by the {@link module:list/list~List list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'numbered'|'bulleted'} type List type that will be handled by this command.\n\t */\n\tconstructor( editor, type ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The type of the list created by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'numbered'|'bulleted'}\n\t\t */\n\t\tthis.type = type == 'bulleted' ? 'bulleted' : 'numbered';\n\n\t\t/**\n\t\t * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @protected\n\t * @param {Object} [options] Options for the executed command.\n\t * @param {module:engine/model/batch~Batch} [options.batch] A batch to collect all the change steps.\n\t * A new batch will be created if this option is not set.\n\t */\n\texecute( options = {} ) {\n\t\tconst document = this.editor.document;\n\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => checkCanBecomeListItem( block, document.schema ) );\n\n\t\t// Whether we are turning off some items.\n\t\tconst turnOff = this.value === true;\n\t\t// If we are turning off items, we are going to rename them to paragraphs.\n\n\t\tdocument.enqueueChanges( () => {\n\t\t\tconst batch = options.batch || document.batch();\n\n\t\t\t// If part of a list got turned off, we need to handle (outdent) all of sub-items of the last turned-off item.\n\t\t\t// To be sure that model is all the time in a good state, we first fix items below turned-off item.\n\t\t\tif ( turnOff ) {\n\t\t\t\t// Start from the model item that is just after the last turned-off item.\n\t\t\t\tlet next = blocks[ blocks.length - 1 ].nextSibling;\n\t\t\t\tlet currentIndent = Number.POSITIVE_INFINITY;\n\t\t\t\tlet changes = [];\n\n\t\t\t\t// Correct indent of all items after the last turned off item.\n\t\t\t\t// Rules that should be followed:\n\t\t\t\t// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n\t\t\t\t// will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n\t\t\t\t// 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n\t\t\t\t// should not end up as a child of any of list items that they were not children of before.\n\t\t\t\t// 3. All other items should have their indent changed relatively to it's parent.\n\t\t\t\t//\n\t\t\t\t// For example:\n\t\t\t\t// 1 * --------\n\t\t\t\t// 2 * --------\n\t\t\t\t// 3 * --------\t\t\t<-- this is turned off.\n\t\t\t\t// 4 * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n\t\t\t\t// 5 * --------\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 6 * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n\t\t\t\t// 7 * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 8 * --------\t\t\t\t<-- this has to become indent = 0.\n\t\t\t\t// 9 * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n\t\t\t\t// 10 * --------\t\t<-- this should still be a child of item above, so indent = 2.\n\t\t\t\t// 11 * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n\t\t\t\t// 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n\t\t\t\t// 13 * --------\n\t\t\t\t// 14 * --------\n\t\t\t\t//\n\t\t\t\t// After turning off 3 the list becomes:\n\t\t\t\t//\n\t\t\t\t// 1 * --------\n\t\t\t\t// 2 * --------\n\t\t\t\t//\n\t\t\t\t// 3 --------\n\t\t\t\t//\n\t\t\t\t// 4 * --------\n\t\t\t\t// 5 * --------\n\t\t\t\t// 6 * --------\n\t\t\t\t// 7 * --------\n\t\t\t\t// 8 * --------\n\t\t\t\t// 9 * --------\n\t\t\t\t// 10 * --------\n\t\t\t\t// 11 * --------\n\t\t\t\t// 12 * --------\n\t\t\t\t// 13 * --------\n\t\t\t\t// 14 * --------\n\t\t\t\t//\n\t\t\t\t// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n\t\t\t\t// those parent-child connection which are possible to maintain are still maintained. It's worth noting\n\t\t\t\t// that this is the same effect that we would be get by multiple use of outdent command. However doing\n\t\t\t\t// it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n\t\t\t\t// less conversion (faster).\n\t\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'indent' ) !== 0 ) {\n\t\t\t\t\t// Check each next list item, as long as its indent is bigger than 0.\n\t\t\t\t\t// If the indent is 0 we are not going to change anything anyway.\n\t\t\t\t\tconst indent = next.getAttribute( 'indent' );\n\n\t\t\t\t\t// We check if that's item indent is lower as current relative indent.\n\t\t\t\t\tif ( indent < currentIndent ) {\n\t\t\t\t\t\t// If it is, current relative indent becomes that indent.\n\t\t\t\t\t\tcurrentIndent = indent;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fix indent relatively to current relative indent.\n\t\t\t\t\t// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n\t\t\t\t\tconst newIndent = indent - currentIndent;\n\n\t\t\t\t\t// Save the entry in changes array. We do not apply it at the moment, because we will need to\n\t\t\t\t\t// reverse the changes so the last item is changed first.\n\t\t\t\t\t// This is to keep model in correct state all the time.\n\t\t\t\t\tchanges.push( { element: next, indent: newIndent } );\n\n\t\t\t\t\t// Find next item.\n\t\t\t\t\tnext = next.nextSibling;\n\t\t\t\t}\n\n\t\t\t\tchanges = changes.reverse();\n\n\t\t\t\tfor ( const item of changes ) {\n\t\t\t\t\tbatch.setAttribute( item.element, 'indent', item.indent );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we are turning on, we might change some items that are already `listItem`s but with different type.\n\t\t\t// Changing one nested list item to other type should also trigger changing all its siblings so the\n\t\t\t// whole nested list is of the same type.\n\t\t\t// Example (assume changing to numbered list):\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\t// * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ------\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ---[--\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t\t<-- already in selection, but does not cause other list items to change because is top-level\n\t\t\t// * ---]--\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- fix, because preceding list item of this item's list is changed\n\t\t\t// * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\tif ( !turnOff ) {\n\t\t\t\t// Find lowest indent among selected items. This will be indicator what is the indent of\n\t\t\t\t// top-most list affected by the command.\n\t\t\t\tlet lowestIndent = Number.POSITIVE_INFINITY;\n\n\t\t\t\tfor ( const item of blocks ) {\n\t\t\t\t\tif ( item.is( 'listItem' ) && item.getAttribute( 'indent' ) < lowestIndent ) {\n\t\t\t\t\t\tlowestIndent = item.getAttribute( 'indent' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Do not execute the fix for top-level lists.\n\t\t\t\tlowestIndent = lowestIndent === 0 ? 1 : lowestIndent;\n\n\t\t\t\t// Fix types of list items that are \"before\" the selected blocks.\n\t\t\t\t_fixType( blocks, true, lowestIndent );\n\n\t\t\t\t// Fix types of list items that are \"after\" the selected blocks.\n\t\t\t\t_fixType( blocks, false, lowestIndent );\n\t\t\t}\n\n\t\t\t// Phew! Now it will be easier :).\n\t\t\t// For each block element that was in the selection, we will either: turn it to list item,\n\t\t\t// turn it to paragraph, or change it's type. Or leave it as it is.\n\t\t\t// Do it in reverse as there might be multiple blocks (same as with changing indents).\n\t\t\tfor ( const element of blocks.reverse() ) {\n\t\t\t\tif ( turnOff && element.name == 'listItem' ) {\n\t\t\t\t\t// We are turning off and the element is a `listItem` - it should be converted to `paragraph`.\n\t\t\t\t\t// List item specific attributes are removed by post fixer.\n\t\t\t\t\tbatch.rename( element, 'paragraph' );\n\t\t\t\t} else if ( !turnOff && element.name != 'listItem' ) {\n\t\t\t\t\t// We are turning on and the element is not a `listItem` - it should be converted to `listItem`.\n\t\t\t\t\t// The order of operations is important to keep model in correct state.\n\t\t\t\t\tbatch.setAttribute( element, 'type', this.type ).setAttribute( element, 'indent', 0 ).rename( element, 'listItem' );\n\t\t\t\t} else if ( !turnOff && element.name == 'listItem' && element.getAttribute( 'type' ) != this.type ) {\n\t\t\t\t\t// We are turning on and the element is a `listItem` but has different type - change it's type and\n\t\t\t\t\t// type of it's all siblings that have same indent.\n\t\t\t\t\tbatch.setAttribute( element, 'type', this.type );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\t// Check whether closest `listItem` ancestor of the position has a correct type.\n\t\tconst listItem = first( this.editor.document.selection.getSelectedBlocks() );\n\n\t\treturn !!listItem && listItem.is( 'listItem' ) && listItem.getAttribute( 'type' ) == this.type;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// If command value is true it means that we are in list item, so the command should be enabled.\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.document.selection;\n\t\tconst schema = this.editor.document.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Otherwise, check if list item can be inserted at the position start.\n\t\treturn checkCanBecomeListItem( firstBlock, schema );\n\t}\n}\n\n// Helper function used when one or more list item have their type changed. Fixes type of other list items\n// that are affected by the change (are in same lists) but are not directly in selection. The function got extracted\n// not to duplicated code, as same fix has to be performed before and after selection.\n//\n// @param {Array.<module:engine/model/node~Node>} blocks Blocks that are in selection.\n// @param {Boolean} isBackward Specified whether fix will be applied for blocks before first selected block (`true`)\n// or blocks after last selected block (`false`).\n// @param {Number} lowestIndent Lowest indent among selected blocks.\nfunction _fixType( blocks, isBackward, lowestIndent ) {\n\t// We need to check previous sibling of first changed item and next siblings of last changed item.\n\tconst startingItem = isBackward ? blocks[ 0 ] : blocks[ blocks.length - 1 ];\n\n\tif ( startingItem.is( 'listItem' ) ) {\n\t\tlet item = startingItem[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t// During processing items, keeps the lowest indent of already processed items.\n\t\t// This saves us from changing too many items.\n\t\t// Following example is for going forward as it is easier to read, however same applies to going backward.\n\t\t// * ------\n\t\t// * ------\n\t\t// * --[---\n\t\t// * ------\t\t<-- `lowestIndent` should be 1\n\t\t// * --]---\t\t<-- `startingItem`, `currentIndent` = 2, `lowestIndent` == 1\n\t\t// * ------\t\t<-- should be fixed, `indent` == 2 == `currentIndent`\n\t\t// * ------\t\t<-- should be fixed, set `currentIndent` to 1, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t<-- should not be fixed, item is in different list, `indent` = 2, `indent` != `currentIndent`\n\t\t// * ------\t\t<-- should be fixed, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t\t<-- break loop (`indent` < `lowestIndent`)\n\t\tlet currentIndent = startingItem.getAttribute( 'indent' );\n\n\t\t// Look back until a list item with indent lower than reference `lowestIndent`.\n\t\t// That would be the parent of nested sublist which contains item having `lowestIndent`.\n\t\twhile ( item && item.is( 'listItem' ) && item.getAttribute( 'indent' ) >= lowestIndent ) {\n\t\t\tif ( currentIndent > item.getAttribute( 'indent' ) ) {\n\t\t\t\tcurrentIndent = item.getAttribute( 'indent' );\n\t\t\t}\n\n\t\t\t// Found an item that is in the same nested sublist.\n\t\t\tif ( item.getAttribute( 'indent' ) == currentIndent ) {\n\t\t\t\t// Just add the item to selected blocks like it was selected by the user.\n\t\t\t\tblocks[ isBackward ? 'unshift' : 'push' ]( item );\n\t\t\t}\n\n\t\t\titem = item[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t}\n\t}\n}\n\n// Checks whether the given block can be replaced by a listItem.\n//\n// @private\n// @param {module:engine/model/element~Element} block A block to be tested.\n// @param {module:engine/model/schema~Schema} schema The schema of the document.\n// @returns {Boolean}\nfunction checkCanBecomeListItem( block, schema ) {\n\treturn schema.check( {\n\t\tname: 'listItem',\n\t\tattributes: [ 'type', 'indent' ],\n\t\tinside: Position.createBefore( block )\n\t} );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-list/src/listcommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/indentcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The list indent command. It is used by the {@link module:list/list~List list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class IndentCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'forward'|'backward'} indentDirection The direction of indent. If it is equal to `backward`, the command\n\t * will outdent a list item.\n\t */\n\tconstructor( editor, indentDirection ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Determines by how much the command will change the list item's indent attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {Number}\n\t\t */\n\t\tthis._indentBy = indentDirection == 'forward' ? 1 : -1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Indents or outdents (depends on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst doc = this.editor.document;\n\t\tconst batch = doc.batch();\n\t\tlet itemsToChange = Array.from( doc.selection.getSelectedBlocks() );\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tconst lastItem = itemsToChange[ itemsToChange.length - 1 ];\n\n\t\t\t// Indenting a list item should also indent all the items that are already sub-items of indented item.\n\t\t\tlet next = lastItem.nextSibling;\n\n\t\t\t// Check all items after last indented item, as long as their indent is bigger than indent of that item.\n\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'indent' ) > lastItem.getAttribute( 'indent' ) ) {\n\t\t\t\titemsToChange.push( next );\n\n\t\t\t\tnext = next.nextSibling;\n\t\t\t}\n\n\t\t\t// We need to be sure to keep model in correct state after each small change, because converters\n\t\t\t// bases on that state and assumes that model is correct.\n\t\t\t// Because of that, if the command outdents items, we will outdent them starting from the last item, as\n\t\t\t// it is safer.\n\t\t\tif ( this._indentBy < 0 ) {\n\t\t\t\titemsToChange = itemsToChange.reverse();\n\t\t\t}\n\n\t\t\tfor ( const item of itemsToChange ) {\n\t\t\t\tconst indent = item.getAttribute( 'indent' ) + this._indentBy;\n\n\t\t\t\t// If indent is lower than 0, it means that the item got outdented when it was not indented.\n\t\t\t\t// This means that we need to convert that list item to paragraph.\n\t\t\t\tif ( indent < 0 ) {\n\t\t\t\t\t// To keep the model as correct as possible, first rename listItem, then remove attributes,\n\t\t\t\t\t// as listItem without attributes is very incorrect and will cause problems in converters.\n\t\t\t\t\t// No need to remove attributes, will be removed by post fixer.\n\t\t\t\t\tbatch.rename( item, 'paragraph' );\n\t\t\t\t}\n\t\t\t\t// If indent is >= 0, change the attribute value.\n\t\t\t\telse {\n\t\t\t\t\tbatch.setAttribute( item, 'indent', indent );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check whether some of changed list items' type should not be fixed.\n\t\t\t// But first, reverse `itemsToChange` again -- we always want to perform those fixes starting from first item (source-wise).\n\t\t\tif ( this._indentBy < 0 ) {\n\t\t\t\titemsToChange = itemsToChange.reverse();\n\t\t\t}\n\n\t\t\tfor ( const item of itemsToChange ) {\n\t\t\t\t_fixType( item, batch );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// Check whether any of position's ancestor is a list item.\n\t\tconst listItem = first( this.editor.document.selection.getSelectedBlocks() );\n\n\t\t// If selection is not in a list item, the command is disabled.\n\t\tif ( !listItem || !listItem.is( 'listItem' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this._indentBy > 0 ) {\n\t\t\t// Cannot indent first item in it's list. Check if before `listItem` is a list item that is in same list.\n\t\t\t// To be in the same list, the item has to have same attributes and cannot be \"split\" by an item with lower indent.\n\t\t\tconst indent = listItem.getAttribute( 'indent' );\n\t\t\tconst type = listItem.getAttribute( 'type' );\n\n\t\t\tlet prev = listItem.previousSibling;\n\n\t\t\twhile ( prev && prev.is( 'listItem' ) && prev.getAttribute( 'indent' ) >= indent ) {\n\t\t\t\tif ( prev.getAttribute( 'indent' ) == indent ) {\n\t\t\t\t\t// The item is on the same level.\n\t\t\t\t\t// If it has same type, it means that we found a preceding sibling from the same list.\n\t\t\t\t\t// If it does not have same type, it means that `listItem` is on different list (this can happen only\n\t\t\t\t\t// on top level lists, though).\n\t\t\t\t\treturn prev.getAttribute( 'type' ) == type;\n\t\t\t\t}\n\n\t\t\t\tprev = prev.previousSibling;\n\t\t\t}\n\n\t\t\t// Could not find similar list item, this means that `listItem` is first in its list.\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n\t\treturn true;\n\t}\n}\n\n// Fixes type of `item` element after it was indented/outdented. Looks for a sibling of `item` that has the same\n// indent and sets `item`'s type to the same as that sibling.\nfunction _fixType( item, batch ) {\n\t// Find a preceding sibling of `item` that is a list item of the same list as `item`.\n\tconst prev = _seekListItem( item, false );\n\n\t// If found, fix type.\n\tif ( prev ) {\n\t\tbatch.setAttribute( item, 'type', prev.getAttribute( 'type' ) );\n\n\t\treturn;\n\t}\n\n\t// If not found, find a following sibling of `item` that is a list item of the same list as `item`.\n\tconst next = _seekListItem( item, true );\n\n\t// If found, fix type.\n\tif ( next ) {\n\t\tbatch.setAttribute( item, 'type', next.getAttribute( 'type' ) );\n\t}\n}\n\n// Seeks for a list item that has same indent as given `item`. May look through next siblings (`seekForward = true`) or\n// previous siblings (`seekForward = false`). Returns found list item or `null` if item has not been found.\nfunction _seekListItem( item, seekForward ) {\n\tlet result = item[ seekForward ? 'nextSibling' : 'previousSibling' ];\n\n\t// Look for the previous/next sibling that has same indent and is before a list item element with lower indent.\n\t// If elements are split by an element with lower indent, they are on different lists.\n\twhile ( result && result.is( 'listItem' ) && result.getAttribute( 'indent' ) >= item.getAttribute( 'indent' ) ) {\n\t\tif ( result.getAttribute( 'indent' ) == item.getAttribute( 'indent' ) ) {\n\t\t\t// We found sibling that is on the same list.\n\t\t\treturn result;\n\t\t}\n\n\t\tresult = result[ seekForward ? 'nextSibling' : 'previousSibling' ];\n\t}\n\n\treturn null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-list/src/indentcommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/viewlistitemelement\n */\n\nimport ViewContainerElement from '@ckeditor/ckeditor5-engine/src/view/containerelement';\n\n/**\n * View element class representing a list item (`<li>`). It extends {@link module:engine/view/containerelement~ContainerElement}\n * and overwrites {@link module:list/viewlistitemelement~ViewListItemElement#getFillerOffset evaluating whether filler offset}\n * is needed.\n *\n * @extends module:engine/view/containerelement~ContainerElement\n */\nexport default class ViewListItemElement extends ViewContainerElement {\n\t/**\n\t * Creates a `<li>` view item.\n\t *\n\t * @param {Object|Iterable} [attrs] A collection of attributes.\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] The list of nodes to be inserted\n\t * into the created element.\n\t */\n\tconstructor( attrs, children ) {\n\t\tsuper( 'li', attrs, children );\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n}\n\n// Implementation of getFillerOffset for ViewListItemElements.\n//\n// @returns {Number|null} Block filler offset or `null` if block filler is not needed.\nfunction getFillerOffset() {\n\tconst hasOnlyLists = !this.isEmpty && ( this.getChild( 0 ).name == 'ul' || this.getChild( 0 ).name == 'ol' );\n\n\treturn this.isEmpty || hasOnlyLists ? 0 : null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-list/src/viewlistitemelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/converters\n */\n\nimport ViewListItemElement from './viewlistitemelement';\n\nimport ModelDocumentFragment from '@ckeditor/ckeditor5-engine/src/model/documentfragment';\nimport ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';\nimport ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';\nimport modelWriter from '@ckeditor/ckeditor5-engine/src/model/writer';\n\nimport ViewContainerElement from '@ckeditor/ckeditor5-engine/src/view/containerelement';\nimport ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\nimport ViewRange from '@ckeditor/ckeditor5-engine/src/view/range';\nimport ViewTreeWalker from '@ckeditor/ckeditor5-engine/src/view/treewalker';\nimport viewWriter from '@ckeditor/ckeditor5-engine/src/view/writer';\n\n/**\n * A model-to-view converter for `listItem` model element insertion.\n *\n * It creates a `<ul><li></li><ul>` (or `<ol>`) view structure out of a `listItem` model element, inserts it at the correct\n * position, and merges the list with surrounding lists (if available).\n *\n * @see module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:insert\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n * @param {Object} conversionApi Conversion interface.\n */\nexport function modelViewInsertion( evt, data, consumable, conversionApi ) {\n\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t!consumable.test( data.item, 'addAttribute:type' ) ||\n\t\t!consumable.test( data.item, 'addAttribute:indent' )\n\t) {\n\t\treturn;\n\t}\n\n\tconsumable.consume( data.item, 'insert' );\n\tconsumable.consume( data.item, 'addAttribute:type' );\n\tconsumable.consume( data.item, 'addAttribute:indent' );\n\n\tconst modelItem = data.item;\n\tconst viewItem = generateLiInUl( modelItem, conversionApi.mapper );\n\n\t// Providing kind of \"default\" insert position in case of converting incorrect model.\n\tconst insertPosition = conversionApi.mapper.toViewPosition( ModelPosition.createBefore( modelItem ) );\n\n\tinjectViewList( modelItem, viewItem, conversionApi.mapper, insertPosition );\n}\n\n/**\n * A model-to-view converter for `type` attribute change on `listItem` model element.\n *\n * This change means that `<li>` elements parent changes from `<ul>` to `<ol>` (or vice versa). This is accomplished\n * by breaking view elements, changing their name and merging them.\n *\n * @see module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:changeAttribute\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n * @param {Object} conversionApi Conversion interface.\n */\nexport function modelViewChangeType( evt, data, consumable, conversionApi ) {\n\tif ( !consumable.consume( data.item, 'changeAttribute:type' ) ) {\n\t\treturn;\n\t}\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\n\t// 1. Break the container after and before the list item.\n\t// This will create a view list with one view list item -- the one that changed type.\n\tviewWriter.breakContainer( ViewPosition.createBefore( viewItem ) );\n\tviewWriter.breakContainer( ViewPosition.createAfter( viewItem ) );\n\n\t// 2. Change name of the view list that holds the changed view item.\n\t// We cannot just change name property, because that would not render properly.\n\tlet viewList = viewItem.parent;\n\tconst listName = data.attributeNewValue == 'numbered' ? 'ol' : 'ul';\n\tviewList = viewWriter.rename( viewList, listName );\n\n\t// 3. Merge the changed view list with other lists, if possible.\n\tmergeViewLists( viewList, viewList.nextSibling );\n\tmergeViewLists( viewList.previousSibling, viewList );\n}\n\n/**\n * A model-to-view converter for `listItem` model element removal.\n *\n * @see module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:remove\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n * @param {Object} conversionApi Conversion interface.\n */\nexport function modelViewRemove( evt, data, consumable, conversionApi ) {\n\tif ( !consumable.consume( data.item, 'remove' ) ) {\n\t\treturn;\n\t}\n\n\tlet viewPosition = conversionApi.mapper.toViewPosition( data.sourcePosition );\n\tviewPosition = viewPosition.getLastMatchingPosition( value => !value.item.is( 'li' ) );\n\n\tconst viewItem = viewPosition.nodeAfter;\n\n\t// 1. Break the container after and before the list item.\n\t// This will create a view list with one view list item -- the one that changed type.\n\tviewWriter.breakContainer( ViewPosition.createBefore( viewItem ) );\n\tviewWriter.breakContainer( ViewPosition.createAfter( viewItem ) );\n\n\t// 2. Remove the UL that contains just the removed <li>.\n\tconst viewList = viewItem.parent;\n\tconst viewListPrev = viewList.previousSibling;\n\tconst removeRange = ViewRange.createOn( viewList );\n\tviewWriter.remove( removeRange );\n\n\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\tmergeViewLists( viewListPrev, viewListPrev.nextSibling );\n\t}\n\n\t// 3. Bring back nested list that was in the removed <li>.\n\thoistNestedLists( data.item.getAttribute( 'indent' ) + 1, data.sourcePosition, removeRange.start, viewItem, conversionApi.mapper );\n\n\t// Unbind this element only if it was moved to graveyard.\n\t// See #847.\n\tif ( data.item.root.rootName == '$graveyard' ) {\n\t\tconversionApi.mapper.unbindModelElement( data.item );\n\t}\n}\n\n/**\n * A model-to-view converter for `indent` attribute change on `listItem` model element.\n *\n * @see module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:changeAttribute\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n * @param {Object} conversionApi Conversion interface.\n */\nexport function modelViewChangeIndent( evt, data, consumable, conversionApi ) {\n\tif ( !consumable.consume( data.item, 'changeAttribute:indent' ) ) {\n\t\treturn;\n\t}\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\n\t// 1. Break the container after and before the list item.\n\t// This will create a view list with one view list item -- the one that changed type.\n\tviewWriter.breakContainer( ViewPosition.createBefore( viewItem ) );\n\tviewWriter.breakContainer( ViewPosition.createAfter( viewItem ) );\n\n\t// 2. Extract view list with changed view list item and merge \"hole\" possibly created by breaking and removing elements.\n\tconst viewList = viewItem.parent;\n\tconst viewListPrev = viewList.previousSibling;\n\tconst removeRange = ViewRange.createOn( viewList );\n\tviewWriter.remove( removeRange );\n\n\t// TODO: get rid of `removePosition` when conversion is done on `changesDone`.\n\tlet removePosition;\n\n\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\tremovePosition = mergeViewLists( viewListPrev, viewListPrev.nextSibling );\n\t}\n\n\tif ( !removePosition ) {\n\t\tremovePosition = removeRange.start;\n\t}\n\n\t// 3. Bring back nested list that was in the removed <li>.\n\thoistNestedLists( data.attributeOldValue + 1, data.range.start, removeRange.start, viewItem, conversionApi.mapper );\n\n\t// 4. Inject view list like it is newly inserted.\n\tinjectViewList( data.item, viewItem, conversionApi.mapper, removePosition );\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/list~List list feature}. This converter is fired for\n * insert change of every model item, and should be fired before the actual converter. The converter checks whether the inserted\n * model item is a non-`listItem` element. If it is, and it is inserted inside a view list, the converter breaks the\n * list so the model element is inserted to the view parent element corresponding to its model parent element.\n *\n * The converter prevents such situations:\n *\n *\t\t// Model: // View:\n *\t\t<listItem>foo</listItem> <ul>\n *\t\t<listItem>bar</listItem> <li>foo</li>\n *\t\t <li>bar</li>\n *\t\t </ul>\n *\n *\t\t// After change: // Correct view guaranteed by this converter:\n *\t\t<listItem>foo</listItem> <ul><li>foo</li></ul><p>xxx</p><ul><li>bar</li></ul>\n *\t\t<paragraph>xxx</paragraph> // Instead of this wrong view state:\n *\t\t<listItem>bar</listItem> <ul><li>foo</li><p>xxx</p><li>bar</li></ul>\n *\n * @see module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:insert\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n * @param {Object} conversionApi Conversion interface.\n */\nexport function modelViewSplitOnInsert( evt, data, consumable, conversionApi ) {\n\tif ( data.item.name != 'listItem' ) {\n\t\tlet viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconst lists = [];\n\n\t\t// Break multiple ULs/OLs if there are.\n\t\t//\n\t\t// Imagine following list:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// Insert paragraph after item 1.1.1:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// In this case 1.1.2 has to become beginning of a new list.\n\t\t// We need to break list before 1.1.2 (obvious), then we need to break list also before 1.2.\n\t\t// Then we need to move those broken pieces one after another and merge:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\twhile ( viewPosition.parent.name == 'ul' || viewPosition.parent.name == 'ol' ) {\n\t\t\tviewPosition = viewWriter.breakContainer( viewPosition );\n\n\t\t\tif ( viewPosition.parent.name != 'li' ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Remove lists that are after inserted element.\n\t\t\t// They will be brought back later, below the inserted element.\n\t\t\tconst removeStart = viewPosition;\n\t\t\tconst removeEnd = ViewPosition.createAt( viewPosition.parent, 'end' );\n\n\t\t\t// Don't remove if there is nothing to remove.\n\t\t\tif ( !removeStart.isEqual( removeEnd ) ) {\n\t\t\t\tconst removed = viewWriter.remove( new ViewRange( removeStart, removeEnd ) );\n\t\t\t\tlists.push( removed );\n\t\t\t}\n\n\t\t\tviewPosition = ViewPosition.createAfter( viewPosition.parent );\n\t\t}\n\n\t\t// Bring back removed lists.\n\t\tif ( lists.length > 0 ) {\n\t\t\tfor ( let i = 0; i < lists.length; i++ ) {\n\t\t\t\tconst previousList = viewPosition.nodeBefore;\n\t\t\t\tconst insertedRange = viewWriter.insert( viewPosition, lists[ i ] );\n\t\t\t\tviewPosition = insertedRange.end;\n\n\t\t\t\t// Don't merge first list! We want a split in that place (this is why this converter is introduced).\n\t\t\t\tif ( i > 0 ) {\n\t\t\t\t\tconst mergePos = mergeViewLists( previousList, previousList.nextSibling );\n\n\t\t\t\t\t// If `mergePos` is in `previousList` it means that the lists got merged.\n\t\t\t\t\t// In this case, we need to fix insert position.\n\t\t\t\t\tif ( mergePos && mergePos.parent == previousList ) {\n\t\t\t\t\t\tviewPosition.offset--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Merge last inserted list with element after it.\n\t\t\tmergeViewLists( viewPosition.nodeBefore, viewPosition.nodeAfter );\n\t\t}\n\t}\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/list~List list feature}. This converter takes care of\n * merging view lists after something is removed or moved from near them.\n *\n * Example:\n *\n *\t\t// Model: // View:\n *\t\t<listItem>foo</listItem> <ul><li>foo</li></ul>\n *\t\t<paragraph>xxx</paragraph> <p>xxx</p>\n *\t\t<listItem>bar</listItem> <ul><li>bar</li></ul>\n *\n *\t\t// After change: // Correct view guaranteed by this converter:\n *\t\t<listItem>foo</listItem> <ul>\n *\t\t<listItem>bar</listItem> <li>foo</li>\n *\t\t <li>bar</li>\n *\t\t </ul>\n *\n * @see module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher#event:remove\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n * @param {Object} conversionApi Conversion interface.\n */\nexport function modelViewMergeAfter( evt, data, consumable, conversionApi ) {\n\tif ( !data.item.is( 'listItem' ) ) {\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.sourcePosition );\n\t\tconst viewItemPrev = viewPosition.nodeBefore;\n\t\tconst viewItemNext = viewPosition.nodeAfter;\n\n\t\t// Merge lists if something (remove, move) was done from inside of list.\n\t\t// Merging will be done only if both items are view lists of the same type.\n\t\t// The check is done inside the helper function.\n\t\tmergeViewLists( viewItemPrev, viewItemNext );\n\t}\n}\n\n/**\n * A view-to-model converter that converts `<li>` view elements into `listItem` model elements.\n *\n * To set correct values of the `type` and `indent` attributes the converter:\n * * checks `<li>`'s parent,\n * * passes the `data.indent` value when `<li>`'s sub-items are converted.\n *\n * @see module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/viewconsumable~ViewConsumable} consumable Values to consume.\n * @param {Object} conversionApi Conversion interface to be used by the callback.\n */\nexport function viewModelConverter( evt, data, consumable, conversionApi ) {\n\tif ( consumable.consume( data.input, { name: true } ) ) {\n\t\t// 1. Create `listItem` model element.\n\t\tconst listItem = new ModelElement( 'listItem' );\n\n\t\t// 2. Handle `listItem` model element attributes.\n\t\tdata.indent = data.indent ? data.indent : 0;\n\t\tlistItem.setAttribute( 'indent', data.indent );\n\n\t\t// Set 'bulleted' as default. If this item is pasted into a context,\n\t\tconst type = data.input.parent && data.input.parent.name == 'ol' ? 'numbered' : 'bulleted';\n\t\tlistItem.setAttribute( 'type', type );\n\n\t\t// 3. Handle `<li>` children.\n\t\tdata.context.push( listItem );\n\n\t\t// `listItem`s created recursively should have bigger indent.\n\t\tdata.indent++;\n\n\t\t// `listItem`s will be kept in flat structure.\n\t\tconst items = new ModelDocumentFragment();\n\t\titems.appendChildren( listItem );\n\n\t\t// Check all children of the converted `<li>`.\n\t\t// At this point we assume there are no \"whitespace\" view text nodes in view list, between view list items.\n\t\t// This should be handled by `<ul>` and `<ol>` converters.\n\t\tfor ( const child of data.input.getChildren() ) {\n\t\t\t// Let's convert the child.\n\t\t\tconst converted = conversionApi.convertItem( child, consumable, data );\n\n\t\t\t// If this is a view list element, we will convert it and concat the result (`listItem` model elements)\n\t\t\t// with already gathered results (in `items` array). `converted` should be a `ModelDocumentFragment`.\n\t\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\t\titems.appendChildren( Array.from( converted.getChildren() ) );\n\t\t\t}\n\t\t\t// If it was not a list it was a \"regular\" list item content. Just append it to `listItem`.\n\t\t\telse {\n\t\t\t\tmodelWriter.insert( ModelPosition.createAt( listItem, 'end' ), converted );\n\t\t\t}\n\t\t}\n\n\t\tdata.indent--;\n\t\tdata.context.pop();\n\n\t\tdata.output = items;\n\t}\n}\n\n/**\n * A view-to-model converter for `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n * This is mostly to clean whitespaces from between `<li>` view elements inside the view list element, however, also\n * incorrect data can be cleared if the view was incorrect.\n *\n * @see module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/viewconsumable~ViewConsumable} consumable Values to consume.\n */\nexport function cleanList( evt, data, consumable ) {\n\tif ( consumable.test( data.input, { name: true } ) ) {\n\t\t// Caching children because when we start removing them iterating fails.\n\t\tconst children = Array.from( data.input.getChildren() );\n\n\t\tfor ( const child of children ) {\n\t\t\tif ( !child.is( 'li' ) ) {\n\t\t\t\tchild.remove();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A view-to-model converter for `<li>` elements that cleans whitespace formatting from the input view.\n *\n * @see module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/viewconsumable~ViewConsumable} consumable Values to consume.\n */\nexport function cleanListItem( evt, data, consumable ) {\n\tif ( consumable.test( data.input, { name: true } ) ) {\n\t\tif ( data.input.childCount === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst children = [ ...data.input.getChildren() ];\n\n\t\tlet foundList = false;\n\t\tlet firstNode = true;\n\n\t\tfor ( const child of children ) {\n\t\t\tif ( foundList && !child.is( 'ul' ) && !child.is( 'ol' ) ) {\n\t\t\t\tchild.remove();\n\t\t\t}\n\n\t\t\tif ( child.is( 'text' ) ) {\n\t\t\t\t// If this is the first node and it's a text node, left-trim it.\n\t\t\t\tif ( firstNode ) {\n\t\t\t\t\tchild.data = child.data.replace( /^\\s+/, '' );\n\t\t\t\t}\n\n\t\t\t\t// If this is the last text node before <ul> or <ol>, right-trim it.\n\t\t\t\tif ( !child.nextSibling || ( child.nextSibling.is( 'ul' ) || child.nextSibling.is( 'ol' ) ) ) {\n\t\t\t\t\tchild.data = child.data.replace( /\\s+$/, '' );\n\t\t\t\t}\n\t\t\t} else if ( child.is( 'ul' ) || child.is( 'ol' ) ) {\n\t\t\t\t// If this is a <ul> or <ol>, do not process it, just mark that we already visited list element.\n\t\t\t\tfoundList = true;\n\t\t\t}\n\n\t\t\tfirstNode = false;\n\t\t}\n\t}\n}\n\n/**\n * The callback for model position to view position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between `listItem` elements that would be incorrectly mapped because of how list items are represented in model\n * and view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:modelToViewPosition\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing additional data and placeholder for mapping result.\n */\nexport function modelToViewPosition( evt, data ) {\n\tconst modelItem = data.modelPosition.nodeBefore;\n\n\tif ( modelItem && modelItem.is( 'listItem' ) ) {\n\t\tconst viewItem = data.mapper.toViewElement( modelItem );\n\t\tconst topmostViewList = viewItem.getAncestors().find( element => element.is( 'ul' ) || element.is( 'ol' ) );\n\t\tconst walker = new ViewTreeWalker( {\n\t\t\tstartPosition: ViewPosition.createAt( viewItem, 0 )\n\t\t} );\n\n\t\tfor ( const value of walker ) {\n\t\t\tif ( value.type == 'elementStart' && value.item.is( 'li' ) ) {\n\t\t\t\tdata.viewPosition = value.previousPosition;\n\n\t\t\t\tbreak;\n\t\t\t} else if ( value.type == 'elementEnd' && value.item == topmostViewList ) {\n\t\t\t\tdata.viewPosition = value.nextPosition;\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * The callback for view position to model position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between `<li>` elements that would be incorrectly mapped because of how list items are represented in model\n * and view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:viewToModelPosition\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing additional data and placeholder for mapping result.\n */\nexport function viewToModelPosition( evt, data ) {\n\tconst viewPos = data.viewPosition;\n\tconst viewParent = viewPos.parent;\n\tconst mapper = data.mapper;\n\n\tif ( viewParent.name == 'ul' || viewParent.name == 'ol' ) {\n\t\t// Position is directly in <ul> or <ol>.\n\t\tif ( !viewPos.isAtEnd ) {\n\t\t\t// If position is not at the end, it must be before <li>.\n\t\t\t// Get that <li>, map it to `listItem` and set model position before that `listItem`.\n\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeAfter );\n\n\t\t\tdata.modelPosition = ModelPosition.createBefore( modelNode );\n\t\t} else {\n\t\t\t// Position is at the end of <ul> or <ol>, so there is no <li> after it to be mapped.\n\t\t\t// There is <li> before the position, but we cannot just map it to `listItem` and set model position after it,\n\t\t\t// because that <li> may contain nested items.\n\t\t\t// We will check \"model length\" of that <li>, in other words - how many `listItem`s are in that <li>.\n\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeBefore );\n\t\t\tconst modelLength = mapper.getModelLength( viewPos.nodeBefore );\n\n\t\t\t// Then we get model position before mapped `listItem` and shift it accordingly.\n\t\t\tdata.modelPosition = ModelPosition.createBefore( modelNode ).getShiftedBy( modelLength );\n\t\t}\n\n\t\tevt.stop();\n\t} else if ( viewParent.name == 'li' && viewPos.nodeBefore && ( viewPos.nodeBefore.name == 'ul' || viewPos.nodeBefore.name == 'ol' ) ) {\n\t\t// In most cases when view position is in <li> it is in text and this is a correct position.\n\t\t// However, if position is after <ul> or <ol> we have to fix it -- because in model <ul>/<ol> are not in the `listItem`.\n\t\tconst modelNode = mapper.toModelElement( viewParent );\n\n\t\t// Check all <ul>s and <ol>s that are in the <li> but before mapped position.\n\t\t// Get model length of those elements and then add it to the offset of `listItem` mapped to the original <li>.\n\t\tlet modelLength = 1; // Starts from 1 because the original <li> has to be counted in too.\n\t\tlet viewList = viewPos.nodeBefore;\n\n\t\twhile ( viewList && ( viewList.is( 'ul' ) || viewList.is( 'ol' ) ) ) {\n\t\t\tmodelLength += mapper.getModelLength( viewList );\n\n\t\t\tviewList = viewList.previousSibling;\n\t\t}\n\n\t\tdata.modelPosition = ModelPosition.createBefore( modelNode ).getShiftedBy( modelLength );\n\n\t\tevt.stop();\n\t}\n}\n\n/**\n * Post-fixer that reacts to changes on document and fixes incorrect model states.\n *\n * Example:\n *\n *\t\t<listItem type=\"bulleted\" indent=0>Item 1</listItem>\n *\t\t<listItem type=\"bulleted\" indent=1>Item 2</listItem> <--- this is removed.\n *\t\t<listItem type=\"bulleted\" indent=2>Item 3</listItem>\n *\n * Should become:\n *\n *\t\t<listItem type=\"bulleted\" indent=0>Item 1</listItem>\n *\t\t<listItem type=\"bulleted\" indent=1>Item 3</listItem> <--- note that indent got post-fixed.\n *\n * @param {module:engine/model/document~Document} document The document to observe.\n * @returns {Function} A callback to be attached to the {@link module:engine/model/document~Document#event:change document change event}.\n */\nexport function modelChangePostFixer( document ) {\n\treturn ( evt, type, changes, batch ) => {\n\t\tif ( batch.type == 'transparent' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type == 'remove' ) {\n\t\t\tconst howMany = changes.range.end.offset - changes.range.start.offset;\n\t\t\tconst sourcePos = changes.sourcePosition._getTransformedByInsertion( changes.range.start, howMany, true );\n\n\t\t\t// Fix list items after the cut-out range.\n\t\t\t// This fix is needed if items in model after cut-out range have now wrong indents compared to their previous siblings.\n\t\t\t_fixItemsIndent( sourcePos, document, batch );\n\t\t\t// This fix is needed if two different nested lists got merged, change types of list items \"below\".\n\t\t\t_fixItemsType( sourcePos, false, document, batch );\n\t\t} else if ( type == 'move' ) {\n\t\t\tconst howMany = changes.range.end.offset - changes.range.start.offset;\n\t\t\tconst sourcePos = changes.sourcePosition._getTransformedByInsertion( changes.range.start, howMany, true );\n\n\t\t\t// Fix list items after the cut-out range.\n\t\t\t// This fix is needed if items in model after cut-out range have now wrong indents compared to their previous siblings.\n\t\t\t_fixItemsIndent( sourcePos, document, batch );\n\t\t\t// This fix is needed if two different nested lists got merged, change types of list items \"below\".\n\t\t\t_fixItemsType( sourcePos, false, document, batch );\n\n\t\t\t// Fix items in moved range.\n\t\t\t// This fix is needed if inserted items are too deeply intended.\n\t\t\t_fixItemsIndent( changes.range.start, document, batch );\n\t\t\t// This fix is needed if one or more first inserted items have different type.\n\t\t\t_fixItemsType( changes.range.start, false, document, batch );\n\n\t\t\t// Fix list items after inserted range.\n\t\t\t// This fix is needed if items in model after inserted range have wrong indents.\n\t\t\t_fixItemsIndent( changes.range.end, document, batch );\n\t\t\t// This fix is needed if one or more last inserted items have different type.\n\t\t\t_fixItemsType( changes.range.end, true, document, batch );\n\t\t} else if ( type == 'rename' && changes.oldName == 'listItem' && changes.newName != 'listItem' ) {\n\t\t\tconst element = changes.element;\n\n\t\t\t// Element name is changed from list to something else. Remove useless attributes.\n\t\t\tdocument.enqueueChanges( () => {\n\t\t\t\tbatch.removeAttribute( element, 'indent' ).removeAttribute( element, 'type' );\n\t\t\t} );\n\n\t\t\tconst changePos = ModelPosition.createAfter( changes.element );\n\n\t\t\t// Fix list items after the renamed element.\n\t\t\t// This fix is needed if there are items after renamed element, those items should start from indent = 0.\n\t\t\t_fixItemsIndent( changePos, document, batch );\n\t\t} else if ( type == 'insert' ) {\n\t\t\t// Fix list items in inserted range.\n\t\t\t// This fix is needed if inserted items are too deeply intended.\n\t\t\t_fixItemsIndent( changes.range.start, document, batch );\n\t\t\t// This fix is needed if one or more first inserted items have different type.\n\t\t\t_fixItemsType( changes.range.start, false, document, batch );\n\n\t\t\t// Fix list items after inserted range.\n\t\t\t// This fix is needed if items in model after inserted range have wrong indents.\n\t\t\t_fixItemsIndent( changes.range.end, document, batch );\n\t\t\t// This fix is needed if one or more last inserted items have different type.\n\t\t\t_fixItemsType( changes.range.end, true, document, batch );\n\t\t}\n\t};\n}\n\n// Helper function for post fixer callback. Performs fixing of model `listElement` items indent attribute. Checks the model at the\n// `changePosition`. Looks at the node before position where change occurred and uses that node as a reference for following list items.\nfunction _fixItemsIndent( changePosition, document, batch ) {\n\tlet nextItem = changePosition.nodeAfter;\n\n\tif ( nextItem && nextItem.name == 'listItem' ) {\n\t\tdocument.enqueueChanges( () => {\n\t\t\tconst prevItem = nextItem.previousSibling;\n\t\t\t// This is the maximum indent that following model list item may have.\n\t\t\tconst maxIndent = prevItem && prevItem.is( 'listItem' ) ? prevItem.getAttribute( 'indent' ) + 1 : 0;\n\n\t\t\t// Check how much the next item needs to be outdented.\n\t\t\tlet outdentBy = nextItem.getAttribute( 'indent' ) - maxIndent;\n\t\t\tconst items = [];\n\n\t\t\twhile ( nextItem && nextItem.name == 'listItem' && nextItem.getAttribute( 'indent' ) > maxIndent ) {\n\t\t\t\tif ( outdentBy > nextItem.getAttribute( 'indent' ) ) {\n\t\t\t\t\toutdentBy = nextItem.getAttribute( 'indent' );\n\t\t\t\t}\n\n\t\t\t\tconst newIndent = nextItem.getAttribute( 'indent' ) - outdentBy;\n\n\t\t\t\titems.push( { item: nextItem, indent: newIndent } );\n\n\t\t\t\tnextItem = nextItem.nextSibling;\n\t\t\t}\n\n\t\t\tif ( items.length > 0 ) {\n\t\t\t\t// Since we are outdenting list items, it is safer to start from the last one (it will maintain correct model state).\n\t\t\t\tfor ( const item of items.reverse() ) {\n\t\t\t\t\tbatch.setAttribute( item.item, 'indent', item.indent );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n// Helper function for post fixer callback. Performs fixing of model nested `listElement` items type attribute.\n// Checks the model at the `changePosition`. Looks at nodes after/before that position and changes those items type\n// to the same as node before/after `changePosition`.\nfunction _fixItemsType( changePosition, fixPrevious, document, batch ) {\n\tlet item = changePosition[ fixPrevious ? 'nodeBefore' : 'nodeAfter' ];\n\n\tif ( !item || !item.is( 'listItem' ) || item.getAttribute( 'indent' ) === 0 ) {\n\t\t// !item - when last item got removed.\n\t\t// !item.is( 'listItem' ) - when first element to fix is not a list item already.\n\t\t// indent === 0 - do not fix if changes are done on top level lists.\n\t\treturn;\n\t}\n\n\tdocument.enqueueChanges( () => {\n\t\tconst refItem = _getBoundaryItemOfSameList( item, !fixPrevious );\n\n\t\tif ( !refItem || refItem == item ) {\n\t\t\t// !refItem - happens if first list item is inserted.\n\t\t\t// refItem == item - happens if last item is inserted.\n\t\t\treturn;\n\t\t}\n\n\t\tconst refIndent = refItem.getAttribute( 'indent' );\n\t\tconst refType = refItem.getAttribute( 'type' );\n\n\t\twhile ( item && item.is( 'listItem' ) && item.getAttribute( 'indent' ) >= refIndent ) {\n\t\t\tif ( item.getAttribute( 'type' ) != refType && item.getAttribute( 'indent' ) == refIndent ) {\n\t\t\t\tbatch.setAttribute( item, 'type', refType );\n\t\t\t}\n\n\t\t\titem = item[ fixPrevious ? 'previousSibling' : 'nextSibling' ];\n\t\t}\n\t} );\n}\n\n/**\n * A fixer for pasted content that includes list items.\n *\n * It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n *\n * Example:\n *\n *\t\t<listItem type=\"bulleted\" indent=0>A</listItem>\n *\t\t<listItem type=\"bulleted\" indent=1>B^</listItem>\n *\t\t// At ^ paste: <listItem type=\"bulleted\" indent=4>X</listItem>\n *\t\t// <listItem type=\"bulleted\" indent=5>Y</listItem>\n *\t\t<listItem type=\"bulleted\" indent=2>C</listItem>\n *\n * Should become:\n *\n *\t\t<listItem type=\"bulleted\" indent=0>A</listItem>\n *\t\t<listItem type=\"bulleted\" indent=1>BX</listItem>\n *\t\t<listItem type=\"bulleted\" indent=2>Y/listItem>\n *\t\t<listItem type=\"bulleted\" indent=2>C</listItem>\n *\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Array} args Arguments of {@link module:engine/controller/datacontroller~DataController#insertContent}.\n */\nexport function modelIndentPasteFixer( evt, [ content, selection ] ) {\n\t// Check whether inserted content starts from a `listItem`. If it does not, it means that there are some other\n\t// elements before it and there is no need to fix indents, because even if we insert that content into a list,\n\t// that list will be broken.\n\t// Note: we also need to handle singular elements because inserting item with indent 0 into 0,1,[],2\n\t// would create incorrect model.\n\tlet item = content.is( 'documentFragment' ) ? content.getChild( 0 ) : content;\n\n\tif ( item && item.is( 'listItem' ) ) {\n\t\t// Get a reference list item. Inserted list items will be fixed according to that item.\n\t\tconst pos = selection.getFirstPosition();\n\t\tlet refItem = null;\n\n\t\tif ( pos.parent.is( 'listItem' ) ) {\n\t\t\trefItem = pos.parent;\n\t\t} else if ( pos.nodeBefore && pos.nodeBefore.is( 'listItem' ) ) {\n\t\t\trefItem = pos.nodeBefore;\n\t\t}\n\n\t\t// If there is `refItem` it means that we do insert list items into an existing list.\n\t\tif ( refItem ) {\n\t\t\t// First list item in `data` has indent equal to 0 (it is a first list item). It should have indent equal\n\t\t\t// to the indent of reference item. We have to fix the first item and all of it's children and following siblings.\n\t\t\t// Indent of all those items has to be adjusted to reference item.\n\t\t\tconst indentChange = refItem.getAttribute( 'indent' );\n\n\t\t\t// Fix only if there is anything to fix.\n\t\t\tif ( indentChange > 0 ) {\n\t\t\t\t// Adjust indent of all \"first\" list items in inserted data.\n\t\t\t\twhile ( item && item.is( 'listItem' ) ) {\n\t\t\t\t\titem.setAttribute( 'indent', item.getAttribute( 'indent' ) + indentChange );\n\n\t\t\t\t\titem = item.nextSibling;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Helper function that creates a `<ul><li></li></ul>` or (`<ol>`) structure out of given `modelItem` model `listItem` element.\n// Then, it binds created view list item (<li>) with model `listItem` element.\n// The function then returns created view list item (<li>).\nfunction generateLiInUl( modelItem, mapper ) {\n\tconst listType = modelItem.getAttribute( 'type' ) == 'numbered' ? 'ol' : 'ul';\n\tconst viewItem = new ViewListItemElement();\n\n\tconst viewList = new ViewContainerElement( listType, null );\n\tviewList.appendChildren( viewItem );\n\n\tmapper.bindElements( modelItem, viewItem );\n\n\treturn viewItem;\n}\n\n// Helper function that seeks for a list item sibling of given model item (or position) which meets given criteria.\n// `options` object may contain one or more of given values (by default they are `false`):\n// `options.getNext` - whether next or previous siblings should be checked (default = previous)\n// `options.checkAllSiblings` - whether all siblings or just the first one should be checked (default = only one),\n// `options.sameIndent` - whether sought sibling should have same indent (default = no),\n// `options.biggerIndent` - whether sought sibling should have bigger indent (default = no).\n// `options.smallerIndent` - whether sought sibling should have smaller indent (default = no).\n// `options.isMapped` - whether sought sibling must be mapped to view (default = no).\n// `options.mapper` - used to map model elements when `isMapped` option is set to true.\n// `options.indent` - used as reference item when first parameter is a position\n// Either `options.sameIndent` or `options.biggerIndent` should be set to `true`.\nfunction getSiblingListItem( modelItemOrPosition, options ) {\n\tconst direction = options.getNext ? 'nextSibling' : 'previousSibling';\n\tconst posDirection = options.getNext ? 'nodeAfter' : 'nodeBefore';\n\tconst checkAllSiblings = !!options.checkAllSiblings;\n\tconst sameIndent = !!options.sameIndent;\n\tconst biggerIndent = !!options.biggerIndent;\n\tconst smallerIndent = !!options.smallerIndent;\n\tconst isMapped = !!options.isMapped;\n\n\tconst indent = modelItemOrPosition instanceof ModelElement ? modelItemOrPosition.getAttribute( 'indent' ) : options.indent;\n\tlet item = modelItemOrPosition instanceof ModelElement ? modelItemOrPosition[ direction ] : modelItemOrPosition[ posDirection ];\n\n\twhile ( item && item.name == 'listItem' ) {\n\t\tconst itemIndent = item.getAttribute( 'indent' );\n\n\t\tif (\n\t\t\t( sameIndent && indent == itemIndent ) ||\n\t\t\t( biggerIndent && indent < itemIndent ) ||\n\t\t\t( smallerIndent && indent > itemIndent )\n\t\t) {\n\t\t\tif ( !isMapped || options.mapper.toViewElement( item ) ) {\n\t\t\t\treturn item;\n\t\t\t} else {\n\t\t\t\titem = item[ direction ];\n\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif ( !checkAllSiblings ) {\n\t\t\treturn null;\n\t\t}\n\n\t\titem = item[ direction ];\n\t}\n\n\treturn null;\n}\n\n// Helper function that takes two parameters, that are expected to be view list elements, and merges them.\n// The merge happen only if both parameters are UL or OL elements.\nfunction mergeViewLists( firstList, secondList ) {\n\tif ( firstList && secondList && ( firstList.name == 'ul' || firstList.name == 'ol' ) && firstList.name == secondList.name ) {\n\t\treturn viewWriter.mergeContainers( ViewPosition.createAfter( firstList ) );\n\t}\n\n\treturn null;\n}\n\n// Helper function that takes model list item element `modelItem`, corresponding view list item element `injectedItem`\n// that is not added to the view and is inside a view list element (`ul` or `ol`) and is that's list only child.\n// The list is inserted at correct position (element breaking may be needed) and then merged with it's siblings.\n// See comments below to better understand the algorithm.\nfunction injectViewList( modelItem, injectedItem, mapper, removePosition ) {\n\tconst injectedList = injectedItem.parent;\n\n\t// Position where view list will be inserted.\n\tlet insertPosition;\n\n\t// 1. Find previous list item that has same or smaller indent. Basically we are looking for a first model item\n\t// that is \"parent\" or \"sibling\" if injected model item.\n\t// If there is no such list item, it means that injected list item is the first item in \"its list\".\n\tlet prevItem = getSiblingListItem( modelItem, { sameIndent: true, smallerIndent: true, checkAllSiblings: true } );\n\n\tif ( prevItem && prevItem.getAttribute( 'indent' ) == modelItem.getAttribute( 'indent' ) ) {\n\t\t// There is a list item with same indent - we found same-level sibling.\n\t\t// Break the list after it. Inserted view item will be inserted in the broken space.\n\t\tconst viewItem = mapper.toViewElement( prevItem );\n\t\tinsertPosition = viewWriter.breakContainer( ViewPosition.createAfter( viewItem ) );\n\t} else {\n\t\t// There is no list item with same indent. Check previous model item.\n\t\tprevItem = modelItem.previousSibling;\n\n\t\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\t\t// // If it is a list item, it has to have lower indent.\n\t\t\t// // It means that inserted item should be added to it as its nested item.\n\t\t\t// insertPosition = mapper.toViewPosition( ModelPosition.createAt( prevItem, 'end' ) );\n\t\t\t// ^ ACTUALLY NOT BECAUSE FIXING DOES NOT WORK PROPERLY.\n\t\t\t// TODO: fix this part of code when conversion from model to view is done on `changesDone` event or post/prefixing is better.\n\t\t\tif ( prevItem.getAttribute( 'indent' ) < modelItem.getAttribute( 'indent' ) ) {\n\t\t\t\t// Lower indent, correct model, previous item is a parent and this model item is its nested item.\n\t\t\t\tinsertPosition = mapper.toViewPosition( ModelPosition.createAt( prevItem, 'end' ) );\n\t\t\t} else {\n\t\t\t\t// Higher indent, incorrect model that is probably being fixed. Inject the view list where it was.\n\t\t\t\t// TODO: get rid of `removePosition` when conversion is done on `changesDone`.\n\t\t\t\tif ( removePosition.parent.is( 'ul' ) || removePosition.parent.is( 'ol' ) ) {\n\t\t\t\t\tinsertPosition = viewWriter.breakContainer( removePosition );\n\t\t\t\t} else {\n\t\t\t\t\tinsertPosition = removePosition;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Previous item is not a list item (or does not exist at all).\n\t\t\t// Just map the position and insert the view item at mapped position.\n\t\t\tinsertPosition = mapper.toViewPosition( ModelPosition.createBefore( modelItem ) );\n\t\t}\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Insert the view item.\n\tviewWriter.insert( insertPosition, injectedList );\n\n\t// 2. Handle possible children of injected model item.\n\t// We have to check if next list item in model has bigger indent. If it has, it means that it and possibly\n\t// some following list items should be nested in the injected view item.\n\t// Look only after model elements that are already mapped to view. Some following model items might not be mapped\n\t// if multiple items in model were inserted/moved at once.\n\tconst nextItem = getSiblingListItem(\n\t\tmodelItem,\n\t\t{ biggerIndent: true, getNext: true, isMapped: true, mapper }\n\t);\n\n\tif ( nextItem ) {\n\t\tconst viewItem = mapper.toViewElement( nextItem );\n\n\t\t// Break the list between found view item and its preceding `<li>`s.\n\t\tviewWriter.breakContainer( ViewPosition.createBefore( viewItem ) );\n\n\t\t// The broken (\"lower\") part will be moved as nested children of the inserted view item.\n\t\tconst sourceStart = ViewPosition.createBefore( viewItem.parent );\n\n\t\tconst lastModelItem = _getBoundaryItemOfSameList( nextItem, false );\n\t\tconst lastViewItem = mapper.toViewElement( lastModelItem );\n\t\tconst sourceEnd = viewWriter.breakContainer( ViewPosition.createAfter( lastViewItem ) );\n\t\tconst sourceRange = new ViewRange( sourceStart, sourceEnd );\n\n\t\tconst targetPosition = ViewPosition.createAt( injectedItem, 'end' );\n\t\tviewWriter.move( sourceRange, targetPosition );\n\t}\n\n\t// Merge inserted view list with its possible neighbour lists.\n\tmergeViewLists( injectedList, injectedList.nextSibling );\n\tmergeViewLists( injectedList.previousSibling, injectedList );\n}\n\n// Helper function that takes all children of given `viewRemovedItem` and moves them in a correct place, according\n// to other given parameters.\nfunction hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStartPosition, viewRemovedItem, mapper ) {\n\t// Find correct previous model list item element.\n\t// The element has to have either same or smaller indent than given reference indent.\n\t// This will be the model element which will get nested items (if it has smaller indent) or sibling items (if it has same indent).\n\t// Keep in mind that such element might not be found, if removed item was the first item.\n\tconst prevModelItem = getSiblingListItem( modelRemoveStartPosition, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tcheckAllSiblings: true,\n\t\tindent: nextIndent\n\t} );\n\n\t// Indent of found element or `null` if the element has not been found.\n\tconst prevIndent = prevModelItem ? prevModelItem.getAttribute( 'indent' ) : null;\n\n\tlet insertPosition;\n\n\tif ( !prevModelItem ) {\n\t\t// If element has not been found, simply insert lists at the position where the removed item was:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1 -------- <--- this is removed, no previous list item, put nested items in place of removed item.\n\t\t// 1.1 -------- <--- this is reference indent.\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\tinsertPosition = viewRemoveStartPosition;\n\t} else if ( prevIndent == nextIndent ) {\n\t\t// If element has been found and has same indent as reference indent it means that nested items should\n\t\t// become siblings of found element:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.2 -------- <--- this is `prevModelItem`.\n\t\t// 2 -------- <--- this is removed, previous list item has indent same as reference indent.\n\t\t// 2.1 -------- <--- this is reference indent, this and 2.2 should become siblings of 1.2.\n\t\t// 2.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.2 --------\n\t\t// 2.1 --------\n\t\t// 2.2 --------\n\t\tconst prevViewList = mapper.toViewElement( prevModelItem ).parent;\n\t\tinsertPosition = ViewPosition.createAfter( prevViewList );\n\t} else {\n\t\t// If element has been found and has smaller indent as reference indent it means that nested items\n\t\t// should become nested items of found item:\n\t\t//\n\t\t// 1 -------- <--- this is `prevModelItem`.\n\t\t// 1.1 -------- <--- this is removed, previous list item has indent smaller than reference indent.\n\t\t// 1.1.1 -------- <--- this is reference indent, this and 1.1.1 should become nested items of 1.\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Note: in this case 1.1.1 have indent 2 while 1 have indent 0. In model that should not be possible,\n\t\t// because following item may have indent bigger only by one. But this is fixed by postfixer.\n\t\tconst modelPosition = ModelPosition.createAt( prevModelItem, 'end' );\n\t\tinsertPosition = mapper.toViewPosition( modelPosition );\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Handle multiple lists. This happens if list item has nested numbered and bulleted lists. Following lists\n\t// are inserted after the first list (no need to recalculate insertion position for them).\n\tfor ( const child of [ ...viewRemovedItem.getChildren() ] ) {\n\t\tif ( child.is( 'ul' ) || child.is( 'ol' ) ) {\n\t\t\tinsertPosition = viewWriter.move( ViewRange.createOn( child ), insertPosition ).end;\n\n\t\t\tmergeViewLists( child, child.nextSibling );\n\t\t\tmergeViewLists( child.previousSibling, child );\n\t\t}\n\t}\n}\n\n// Helper function to obtain the first or the last model list item which is in on the same indent level as given `item`.\nfunction _getBoundaryItemOfSameList( item, getFirst ) {\n\tconst indent = item.getAttribute( 'indent' );\n\tconst direction = getFirst ? 'previousSibling' : 'nextSibling';\n\n\tlet result = item;\n\n\twhile ( item[ direction ] && item[ direction ].is( 'listItem' ) && item[ direction ].getAttribute( 'indent' ) >= indent ) {\n\t\titem = item[ direction ];\n\n\t\tif ( item.getAttribute( 'indent' ) == indent ) {\n\t\t\tresult = item;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// Helper function that for given `view.Position`, returns a `view.Position` that is after all `view.UIElement`s that\n// are after given position.\n// For example:\n// <container:p>foo^<ui:span></ui:span><ui:span></ui:span>bar</contain:p>\n// For position ^, a position before \"bar\" will be returned.\nfunction positionAfterUiElements( viewPosition ) {\n\treturn viewPosition.getLastMatchingPosition( value => value.item.is( 'uiElement' ) );\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-list/src/converters.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/listengine\n */\n\nimport ListCommand from './listcommand';\nimport IndentCommand from './indentcommand';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';\n\nimport {\n\tcleanList,\n\tcleanListItem,\n\tmodelViewInsertion,\n\tmodelViewChangeType,\n\tmodelViewMergeAfter,\n\tmodelViewRemove,\n\tmodelViewSplitOnInsert,\n\tmodelViewChangeIndent,\n\tmodelChangePostFixer,\n\tmodelIndentPasteFixer,\n\tviewModelConverter,\n\tmodelToViewPosition,\n\tviewToModelPosition\n} from './converters';\n\n/**\n * The engine of the list feature. It handles creating, editing and removing lists and list items.\n * It registers the `numberedList`, `bulletedList`, `indentList` and `outdentList` commands.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListEngine extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Paragraph ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Schema.\n\t\t// Note: in case `$block` will be ever allowed in `listItem`, keep in mind that this feature\n\t\t// uses `Selection#getSelectedBlocks()` without any additional processing to obtain all selected list items.\n\t\t// If there are blocks allowed inside list item, algorithms using `getSelectedBlocks()` will have to be modified.\n\t\tconst schema = editor.document.schema;\n\t\tschema.registerItem( 'listItem', '$block' );\n\t\tschema.allow( {\n\t\t\tname: 'listItem',\n\t\t\tinside: '$root',\n\t\t\tattributes: [ 'type', 'indent' ]\n\t\t} );\n\t\tschema.requireAttributes( 'listItem', [ 'type', 'indent' ] );\n\n\t\t// Converters.\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\tthis.editor.document.on( 'change', modelChangePostFixer( this.editor.document ), { priority: 'high' } );\n\n\t\t// Unbind all moved model elements before conversion happens. This is important for converters.\n\t\t// TODO: fix this when changes are converted on `changesDone`.\n\t\tthis.editor.document.on( 'change', ( evt, type, changes ) => {\n\t\t\tif ( type == 'move' ) {\n\t\t\t\tfor ( const item of changes.range.getItems() ) {\n\t\t\t\t\tif ( item.is( 'listItem' ) ) {\n\t\t\t\t\t\tediting.mapper.unbindModelElement( item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\tediting.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t\tdata.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\n\t\tediting.mapper.on( 'modelToViewPosition', modelToViewPosition );\n\t\tediting.mapper.on( 'viewToModelPosition', viewToModelPosition );\n\t\tdata.mapper.on( 'modelToViewPosition', modelToViewPosition );\n\n\t\tediting.modelToView.on( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\tediting.modelToView.on( 'insert:listItem', modelViewInsertion );\n\t\tdata.modelToView.on( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\tdata.modelToView.on( 'insert:listItem', modelViewInsertion );\n\n\t\t// Only change converter is needed. List item's type attribute is required, so it's adding is handled when\n\t\t// list item is added and you cannot remove it.\n\t\tediting.modelToView.on( 'changeAttribute:type:listItem', modelViewChangeType );\n\t\tdata.modelToView.on( 'changeAttribute:type:listItem', modelViewChangeType );\n\n\t\tediting.modelToView.on( 'remove:listItem', modelViewRemove );\n\t\tediting.modelToView.on( 'remove', modelViewMergeAfter, { priority: 'low' } );\n\t\tdata.modelToView.on( 'remove:listItem', modelViewRemove );\n\t\tdata.modelToView.on( 'remove', modelViewMergeAfter, { priority: 'low' } );\n\n\t\tediting.modelToView.on( 'changeAttribute:indent:listItem', modelViewChangeIndent );\n\t\tdata.modelToView.on( 'changeAttribute:indent:listItem', modelViewChangeIndent );\n\n\t\tdata.viewToModel.on( 'element:ul', cleanList, { priority: 'high' } );\n\t\tdata.viewToModel.on( 'element:ol', cleanList, { priority: 'high' } );\n\t\tdata.viewToModel.on( 'element:li', cleanListItem, { priority: 'high' } );\n\t\tdata.viewToModel.on( 'element:li', viewModelConverter );\n\n\t\t// Fix indentation of pasted items.\n\t\tdata.on( 'insertContent', modelIndentPasteFixer, { priority: 'high' } );\n\n\t\t// Register commands for numbered and bulleted list.\n\t\teditor.commands.add( 'numberedList', new ListCommand( editor, 'numbered' ) );\n\t\teditor.commands.add( 'bulletedList', new ListCommand( editor, 'bulleted' ) );\n\n\t\t// Register commands for indenting.\n\t\teditor.commands.add( 'indentList', new IndentCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'outdentList', new IndentCommand( editor, 'backward' ) );\n\t}\n}\n\nfunction getViewListItemLength( element ) {\n\tlet length = 1;\n\n\tfor ( const child of element.getChildren() ) {\n\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\tfor ( const item of child.getChildren() ) {\n\t\t\t\tlength += getViewListItemLength( item );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn length;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-list/src/listengine.js\n// module id = null\n// module chunks = ","import apply from './_apply';\nimport toInteger from './toInteger';\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * Creates a function that invokes `func` with the `this` binding of the\n * created function and arguments from `start` and beyond provided as\n * an array.\n *\n * **Note:** This method is based on the\n * [rest parameter](https://mdn.io/rest_parameters).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.rest(function(what, names) {\n * return what + ' ' + _.initial(names).join(', ') +\n * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n * });\n *\n * say('hello', 'fred', 'barney', 'pebbles');\n * // => 'hello fred, barney, & pebbles'\n */\nfunction rest(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n switch (start) {\n case 0: return func.call(this, array);\n case 1: return func.call(this, args[0], array);\n case 2: return func.call(this, args[0], args[1], array);\n }\n var otherArgs = Array(start + 1);\n index = -1;\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = array;\n return apply(func, this, otherArgs);\n };\n}\n\nexport default rest;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/rest.js\n// module id = null\n// module chunks = ","/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetPrototype = Object.getPrototypeOf;\n\n/**\n * Gets the `[[Prototype]]` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {null|Object} Returns the `[[Prototype]]`.\n */\nfunction getPrototype(value) {\n return nativeGetPrototype(Object(value));\n}\n\nexport default getPrototype;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_getPrototype.js\n// module id = null\n// module chunks = ","/**\n * Checks if `value` is a host object in IE < 9.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n */\nfunction isHostObject(value) {\n // Many host objects are `Object` objects that can coerce to strings\n // despite having improperly defined `toString` methods.\n var result = false;\n if (value != null && typeof value.toString != 'function') {\n try {\n result = !!(value + '');\n } catch (e) {}\n }\n return result;\n}\n\nexport default isHostObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_isHostObject.js\n// module id = null\n// module chunks = ","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\nexport default isObjectLike;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isObjectLike.js\n// module id = null\n// module chunks = ","import getPrototype from './_getPrototype';\nimport isHostObject from './_isHostObject';\nimport isObjectLike from './isObjectLike';\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object,\n * else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) ||\n objectToString.call(value) != objectTag || isHostObject(value)) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return (typeof Ctor == 'function' &&\n Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);\n}\n\nexport default isPlainObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isPlainObject.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/config\n */\n\nimport isPlainObject from './lib/lodash/isPlainObject';\n\n/**\n * Handles a configuration dictionary.\n */\nexport default class Config {\n\t/**\n\t * Creates an instance of the {@link ~Config} class.\n\t *\n\t * @param {Object} [configurations] The initial configurations to be set. Usually, provided by the user.\n\t * @param {Object} [defaultConfigurations] The default configurations. Usually, provided by the system.\n\t */\n\tconstructor( configurations, defaultConfigurations ) {\n\t\t/**\n\t\t * Store for the whole configuration.\n\t\t *\n\t\t * @private\n\t\t * @member {Object}\n\t\t */\n\t\tthis._config = {};\n\n\t\t// Set default configuration.\n\t\tif ( defaultConfigurations ) {\n\t\t\tthis.define( defaultConfigurations );\n\t\t}\n\n\t\t// Set initial configuration.\n\t\tif ( configurations ) {\n\t\t\tthis._setObjectToTarget( this._config, configurations );\n\t\t}\n\t}\n\n\t/**\n\t * Set configuration values.\n\t *\n\t * It accepts both a name/value pair or an object, which properties and values will be used to set\n\t * configurations.\n\t *\n\t * It also accepts setting a \"deep configuration\" by using dots in the name. For example, `'resize.width'` sets\n\t * the value for the `width` configuration in the `resize` subset.\n\t *\n\t *\t\tconfig.set( 'width', 500 );\n\t *\t\tconfig.set( 'toolbar.collapsed', true );\n\t *\n\t *\t\t// Equivalent to:\n\t *\t\tconfig.set( {\n\t *\t\t\twidth: 500\n\t *\t\t\ttoolbar: {\n\t *\t\t\t\tcollapsed: true\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * Passing an object as the value will amend the configuration, not replace it.\n\t *\n\t *\t\tconfig.set( 'toolbar', {\n\t *\t\t\tcollapsed: true,\n\t *\t\t} );\n\t *\n\t *\t\tconfig.set( 'toolbar', {\n\t *\t\t\tcolor: 'red',\n\t *\t\t} );\n\t *\n\t *\t\tconfig.get( 'toolbar.collapsed' ); // true\n\t *\t\tconfig.get( 'toolbar.color' ); // 'red'\n\t *\n\t * @param {String|Object} name The configuration name or an object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t * @param {*} value The configuration value. Used if a name is passed.\n\t */\n\tset( name, value ) {\n\t\tthis._setToTarget( this._config, name, value );\n\t}\n\n\t/**\n\t * Does exactly the same as {@link #set} with one exception passed configuration extends\n\t * existing one, but does not overwrite already defined values.\n\t *\n\t * This method is supposed to be called by plugin developers to setup plugin's configurations. It would be\n\t * rarely used for other needs.\n\t *\n\t * @param {String|Object} name The configuration name or an object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t * @param {*} value The configuration value. Used if a name is passed.\n\t */\n\tdefine( name, value ) {\n\t\tconst isDefine = true;\n\n\t\tthis._setToTarget( this._config, name, value, isDefine );\n\t}\n\n\t/**\n\t * Gets the value for a configuration entry.\n\t *\n\t *\t\tconfig.get( 'name' );\n\t *\n\t * Deep configurations can be retrieved by separating each part with a dot.\n\t *\n\t *\t\tconfig.get( 'toolbar.collapsed' );\n\t *\n\t * @param {String} name The configuration name. Configuration names are case-sensitive.\n\t * @returns {*} The configuration value or `undefined` if the configuration entry was not found.\n\t */\n\tget( name ) {\n\t\treturn this._getFromSource( this._config, name );\n\t}\n\n\t/**\n\t * Saves passed configuration to the specified target (nested object).\n\t *\n\t * @private\n\t * @param {Object} target Nested config object.\n\t * @param {String|Object} name The configuration name or an object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t * @param {*} value The configuration value. Used if a name is passed.\n\t * @param {Boolean} [isDefine=false] Define if passed configuration should overwrite existing one.\n\t */\n\t_setToTarget( target, name, value, isDefine = false ) {\n\t\t// In case of an object, iterate through it and call `_setToTarget` again for each property.\n\t\tif ( isPlainObject( name ) ) {\n\t\t\tthis._setObjectToTarget( target, name, isDefine );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].\n\t\tconst parts = name.split( '.' );\n\n\t\t// Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.\n\t\tname = parts.pop();\n\n\t\t// Iterate over parts to check if currently stored configuration has proper structure.\n\t\tfor ( const part of parts ) {\n\t\t\t// If there is no object for specified part then create one.\n\t\t\tif ( !isPlainObject( target[ part ] ) ) {\n\t\t\t\ttarget[ part ] = {};\n\t\t\t}\n\n\t\t\t// Nested object becomes a target.\n\t\t\ttarget = target[ part ];\n\t\t}\n\n\t\t// In case of value is an object.\n\t\tif ( isPlainObject( value ) ) {\n\t\t\t// We take care of proper config structure.\n\t\t\tif ( !isPlainObject( target[ name ] ) ) {\n\t\t\t\ttarget[ name ] = {};\n\t\t\t}\n\n\t\t\ttarget = target[ name ];\n\n\t\t\t// And iterate through this object calling `_setToTarget` again for each property.\n\t\t\tthis._setObjectToTarget( target, value, isDefine );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Do nothing if we are defining configuration for non empty name.\n\t\tif ( isDefine && typeof target[ name ] != 'undefined' ) {\n\t\t\treturn;\n\t\t}\n\n\t\ttarget[ name ] = value;\n\t}\n\n\t/**\n\t * Get specified configuration from specified source (nested object).\n\t *\n\t * @private\n\t * @param {Object} source level of nested object.\n\t * @param {String} name The configuration name. Configuration names are case-sensitive.\n\t * @returns {*} The configuration value or `undefined` if the configuration entry was not found.\n\t */\n\t_getFromSource( source, name ) {\n\t\t// The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].\n\t\tconst parts = name.split( '.' );\n\n\t\t// Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.\n\t\tname = parts.pop();\n\n\t\t// Iterate over parts to check if currently stored configuration has proper structure.\n\t\tfor ( const part of parts ) {\n\t\t\tif ( !isPlainObject( source[ part ] ) ) {\n\t\t\t\tsource = null;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Nested object becomes a source.\n\t\t\tsource = source[ part ];\n\t\t}\n\n\t\t// Always returns undefined for non existing configuration\n\t\treturn source ? source[ name ] : undefined;\n\t}\n\n\t/**\n\t * Iterates through passed object and calls {@link #_setToTarget} method with object key and value for each property.\n\t *\n\t * @private\n\t * @param {Object} target Nested config object.\n\t * @param {Object} configuration Configuration data set\n\t * @param {Boolean} [isDefine] Defines if passed configuration is default configuration or not.\n\t */\n\t_setObjectToTarget( target, configuration, isDefine ) {\n\t\tObject.keys( configuration ).forEach( key => {\n\t\t\tthis._setToTarget( target, key, configuration[ key ], isDefine );\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/config.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugincollection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\n/**\n * Manages a list of CKEditor plugins, including loading, resolving dependencies and initialization.\n */\nexport default class PluginCollection {\n\t/**\n\t * Creates an instance of the PluginCollection class.\n\t * Allows loading and initializing plugins and their dependencies.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {Array.<Function>} [availablePlugins] Plugins (constructors) which the collection will be able to use\n\t * when {@link module:core/plugincollection~PluginCollection#load} is used with plugin names (strings, instead of constructors).\n\t * Usually, the editor will pass its built-in plugins to the collection so they can later be\n\t * used in `config.plugins` or `config.removePlugins` by names.\n\t */\n\tconstructor( editor, availablePlugins = [] ) {\n\t\t/**\n\t\t * @protected\n\t\t * @member {module:core/editor/editor~Editor} module:core/plugin~PluginCollection#_editor\n\t\t */\n\t\tthis._editor = editor;\n\n\t\t/**\n\t\t * Map of plugin constructors which can be retrieved by their names.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map.<String|Function,Function>} module:core/plugin~PluginCollection#_availablePlugins\n\t\t */\n\t\tthis._availablePlugins = new Map();\n\n\t\t/**\n\t\t * @protected\n\t\t * @member {Map} module:core/plugin~PluginCollection#_plugins\n\t\t */\n\t\tthis._plugins = new Map();\n\n\t\tfor ( const PluginConstructor of availablePlugins ) {\n\t\t\tthis._availablePlugins.set( PluginConstructor, PluginConstructor );\n\n\t\t\tif ( PluginConstructor.pluginName ) {\n\t\t\t\tthis._availablePlugins.set( PluginConstructor.pluginName, PluginConstructor );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Collection iterator. Returns `[ PluginConstructor, pluginInstance ]` pairs.\n\t */\n\t* [ Symbol.iterator ]() {\n\t\tfor ( const entry of this._plugins ) {\n\t\t\tif ( typeof entry[ 0 ] == 'function' ) {\n\t\t\t\tyield entry;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets the plugin instance by its constructor or name.\n\t *\n\t * @param {Function|String} key The plugin constructor or {@link module:core/plugin~PluginInterface.pluginName name}.\n\t * @returns {module:core/plugin~PluginInterface}\n\t */\n\tget( key ) {\n\t\treturn this._plugins.get( key );\n\t}\n\n\t/**\n\t * Loads a set of plugins and adds them to the collection.\n\t *\n\t * @param {Array.<Function|String>} plugins An array of {@link module:core/plugin~PluginInterface plugin constructors}\n\t * or {@link module:core/plugin~PluginInterface.pluginName plugin names}. The second option (names) work only if\n\t * `availablePlugins` were passed to the {@link #constructor}.\n\t * @param {Array.<String|Function>} [removePlugins] Names of plugins or plugin constructors\n\t * which should not be loaded (despite being specified in the `plugins` array).\n\t * @returns {Promise} A promise which gets resolved once all plugins are loaded and available into the\n\t * collection.\n\t * @returns {Promise.<Array.<module:core/plugin~PluginInterface>>} returns.loadedPlugins The array of loaded plugins.\n\t */\n\tload( plugins, removePlugins = [] ) {\n\t\tconst that = this;\n\t\tconst editor = this._editor;\n\t\tconst loading = new Set();\n\t\tconst loaded = [];\n\n\t\tconst pluginConstructors = mapToAvailableConstructors( plugins );\n\t\tconst removePluginConstructors = mapToAvailableConstructors( removePlugins );\n\t\tconst missingPlugins = getMissingPluginNames( plugins );\n\n\t\tif ( missingPlugins ) {\n\t\t\t// TODO update this error docs with links to docs because it will be a frequent problem.\n\n\t\t\t/**\n\t\t\t * Some plugins are not available and could not be loaded.\n\t\t\t *\n\t\t\t * Plugin classes (constructors) need to be provided to the editor before they can be loaded by name.\n\t\t\t * This is usually done by the builder by setting the {@link module:core/editor/editor~Editor.build}\n\t\t\t * property.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the {@glink builds/index CKEditor 5 Builds}** it means\n\t\t\t * that you try to enable a plugin which was not included into that build. This may a be due to a typo\n\t\t\t * in the plugin name or simply because that plugin is not part of this build. In the latter scenario,\n\t\t\t * read more about {@glink builds/guides/development/custom-builds custom builds}.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the editor creators directly** (not a build), then it means\n\t\t\t * that you tried loading plugins by name. However, unlike CKEditor 4, CKEditor 5 does not implement a \"plugin loader\".\n\t\t\t * This means that CKEditor 5 does not know where to load the plugin modules from. Therefore, you need to\n\t\t\t * provide each plugin through reference (as a constructor function). Check out the examples in\n\t\t\t * {@glink builds/guides/integration/advanced-setup#Scenario-2-Building-from-source \"Building from source\"}.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-not-found\n\t\t\t * @param {Array.<String>} plugins The name of the plugins which could not be loaded.\n\t\t\t */\n\t\t\tconst errorMsg = 'plugincollection-plugin-not-found: Some plugins are not available and could not be loaded.';\n\n\t\t\t// Log the error so it's more visible on the console. Hopefully, for better DX.\n\t\t\tlog.error( errorMsg, { plugins: missingPlugins } );\n\n\t\t\treturn Promise.reject( new CKEditorError( errorMsg, { plugins: missingPlugins } ) );\n\t\t}\n\n\t\treturn Promise.all( pluginConstructors.map( loadPlugin ) )\n\t\t\t.then( () => loaded );\n\n\t\tfunction loadPlugin( PluginConstructor ) {\n\t\t\tif ( removePluginConstructors.includes( PluginConstructor ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The plugin is already loaded or being loaded - do nothing.\n\t\t\tif ( that.get( PluginConstructor ) || loading.has( PluginConstructor ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn instantiatePlugin( PluginConstructor )\n\t\t\t\t.catch( err => {\n\t\t\t\t\t/**\n\t\t\t\t\t * It was not possible to load the plugin.\n\t\t\t\t\t *\n\t\t\t\t\t * This is a generic error logged to the console when a JavaSript error is thrown during one of\n\t\t\t\t\t * the plugins initialization.\n\t\t\t\t\t *\n\t\t\t\t\t * If you correctly handled a promise returned by the editor's `create()` method (like shown below)\n\t\t\t\t\t * you will find the original error logged on the console too:\n\t\t\t\t\t *\n\t\t\t\t\t *\t\tClassicEditor.create( document.getElementById( 'editor' ) )\n\t\t\t\t\t *\t\t\t.then( editor => {\n\t\t\t\t\t *\t\t\t\t// ...\n\t\t\t\t\t * \t\t\t} )\n\t\t\t\t\t *\t\t\t.catch( error => {\n\t\t\t\t\t *\t\t\t\tconsole.error( error );\n\t\t\t\t\t *\t\t\t} );\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-load\n\t\t\t\t\t * @param {String} plugin The name of the plugin that could not be loaded.\n\t\t\t\t\t */\n\t\t\t\t\tlog.error( 'plugincollection-load: It was not possible to load the plugin.', { plugin: PluginConstructor } );\n\n\t\t\t\t\tthrow err;\n\t\t\t\t} );\n\t\t}\n\n\t\tfunction instantiatePlugin( PluginConstructor ) {\n\t\t\treturn new Promise( resolve => {\n\t\t\t\tloading.add( PluginConstructor );\n\n\t\t\t\tif ( PluginConstructor.requires ) {\n\t\t\t\t\tPluginConstructor.requires.forEach( RequiredPluginConstructorOrName => {\n\t\t\t\t\t\tconst RequiredPluginConstructor = getPluginConstructor( RequiredPluginConstructorOrName );\n\n\t\t\t\t\t\tif ( removePlugins.includes( RequiredPluginConstructor ) ) {\n\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t * Cannot load a plugin because one of its dependencies is listed in the `removePlugins` option.\n\t\t\t\t\t\t\t *\n\t\t\t\t\t\t\t * @error plugincollection-required\n\t\t\t\t\t\t\t * @param {Function} plugin The required plugin.\n\t\t\t\t\t\t\t * @param {Function} requiredBy The parent plugin.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t\t\t'plugincollection-required: Cannot load a plugin because one of its dependencies is listed in' +\n\t\t\t\t\t\t\t\t'the `removePlugins` option.',\n\t\t\t\t\t\t\t\t{ plugin: RequiredPluginConstructor, requiredBy: PluginConstructor }\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tloadPlugin( RequiredPluginConstructor );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tconst plugin = new PluginConstructor( editor );\n\t\t\t\tthat._add( PluginConstructor, plugin );\n\t\t\t\tloaded.push( plugin );\n\n\t\t\t\tresolve();\n\t\t\t} );\n\t\t}\n\n\t\tfunction getPluginConstructor( PluginConstructorOrName ) {\n\t\t\tif ( typeof PluginConstructorOrName == 'function' ) {\n\t\t\t\treturn PluginConstructorOrName;\n\t\t\t}\n\n\t\t\treturn that._availablePlugins.get( PluginConstructorOrName );\n\t\t}\n\n\t\tfunction getMissingPluginNames( plugins ) {\n\t\t\tconst missingPlugins = [];\n\n\t\t\tfor ( const pluginNameOrConstructor of plugins ) {\n\t\t\t\tif ( !getPluginConstructor( pluginNameOrConstructor ) ) {\n\t\t\t\t\tmissingPlugins.push( pluginNameOrConstructor );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn missingPlugins.length ? missingPlugins : null;\n\t\t}\n\n\t\tfunction mapToAvailableConstructors( plugins ) {\n\t\t\treturn plugins\n\t\t\t\t.map( pluginNameOrConstructor => getPluginConstructor( pluginNameOrConstructor ) )\n\t\t\t\t.filter( PluginConstructor => !!PluginConstructor );\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all loaded plugins.\n\t *\n\t * @returns {Promise}\n\t */\n\tdestroy() {\n\t\tconst promises = Array.from( this )\n\t\t\t.map( ( [ , pluginInstance ] ) => pluginInstance )\n\t\t\t.filter( pluginInstance => typeof pluginInstance.destroy == 'function' )\n\t\t\t.map( pluginInstance => pluginInstance.destroy() );\n\n\t\treturn Promise.all( promises );\n\t}\n\n\t/**\n\t * Adds the plugin to the collection. Exposed mainly for testing purposes.\n\t *\n\t * @protected\n\t * @param {Function} PluginConstructor The plugin constructor.\n\t * @param {module:core/plugin~PluginInterface} plugin The instance of the plugin.\n\t */\n\t_add( PluginConstructor, plugin ) {\n\t\tthis._plugins.set( PluginConstructor, plugin );\n\n\t\tconst pluginName = PluginConstructor.pluginName;\n\n\t\tif ( !pluginName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this._plugins.has( pluginName ) ) {\n\t\t\t/**\n\t\t\t * Two plugins with the same {@link module:core/plugin~PluginInterface.pluginName} were loaded.\n\t\t\t * This may lead to runtime conflicts between these plugins. This usually means that incorrect\n\t\t\t * params were passed to {@link module:core/editor/editor~Editor.create}.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-name-conflict\n\t\t\t * @param {String} pluginName The duplicated plugin name.\n\t\t\t * @param {Function} plugin1 The first plugin constructor.\n\t\t\t * @param {Function} plugin2 The second plugin constructor.\n\t\t\t */\n\t\t\tlog.warn(\n\t\t\t\t'plugincollection-plugin-name-conflict: Two plugins with the same name were loaded.',\n\t\t\t\t{ pluginName, plugin1: this._plugins.get( pluginName ).constructor, plugin2: PluginConstructor }\n\t\t\t);\n\t\t} else {\n\t\t\tthis._plugins.set( pluginName, plugin );\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/src/plugincollection.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/commandcollection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Collection of commands. Its instance is available in {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n */\nexport default class CommandCollection {\n\t/**\n\t * Creates collection instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Command map.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._commands = new Map();\n\t}\n\n\t/**\n\t * Registers a new command.\n\t *\n\t * @param {String} commandName The name of the command.\n\t * @param {module:core/command~Command} command\n\t */\n\tadd( commandName, command ) {\n\t\tthis._commands.set( commandName, command );\n\t}\n\n\t/**\n\t * Retrieves a command from the collection.\n\t *\n\t * @param {String} commandName The name of the command.\n\t * @returns {module:core/command~Command}\n\t */\n\tget( commandName ) {\n\t\treturn this._commands.get( commandName );\n\t}\n\n\t/**\n\t * Executes a command.\n\t *\n\t * @param {String} commandName The name of the command.\n\t */\n\texecute( commandName, ...args ) {\n\t\tconst command = this.get( commandName );\n\n\t\tif ( !command ) {\n\t\t\t/**\n\t\t\t * Command does not exist.\n\t\t\t *\n\t\t\t * @error commandcollection-command-not-found\n\t\t\t * @param {String} commandName Name of the command.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'commandcollection-command-not-found: Command does not exist.', { commandName } );\n\t\t}\n\n\t\tcommand.execute( ...args );\n\t}\n\n\t/**\n\t * Returns iterator of command names.\n\t *\n\t * @returns {Iterator.<String>}\n\t */\n\t* names() {\n\t\tyield* this._commands.keys();\n\t}\n\n\t/**\n\t * Returns iterator of command instances.\n\t *\n\t * @returns {Iterator.<module:core/command~Command>}\n\t */\n\t* commands() {\n\t\tyield* this._commands.values();\n\t}\n\n\t/**\n\t * Collection iterator.\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._commands[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Destroys all collection commands.\n\t */\n\tdestroy() {\n\t\tfor ( const command of this.commands() ) {\n\t\t\tcommand.destroy();\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/src/commandcollection.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/eventinfo\n */\n\nimport spy from './spy';\n\n/**\n * The event object passed to event callbacks. It is used to provide information about the event as well as a tool to\n * manipulate it.\n */\nexport default class EventInfo {\n\t/**\n\t * @param {Object} source The emitter.\n\t * @param {String} name The event name.\n\t */\n\tconstructor( source, name ) {\n\t\t/**\n\t\t * The object that fired the event.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Object}\n\t\t */\n\t\tthis.source = source;\n\n\t\t/**\n\t\t * The event name.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Path this event has followed. See {@link module:utils/emittermixin~EmitterMixin#delegate}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<Object>}\n\t\t */\n\t\tthis.path = [];\n\n\t\t// The following methods are defined in the constructor because they must be re-created per instance.\n\n\t\t/**\n\t\t * Stops the event emitter to call further callbacks for this event interaction.\n\t\t *\n\t\t * @method #stop\n\t\t */\n\t\tthis.stop = spy();\n\n\t\t/**\n\t\t * Removes the current callback from future interactions of this event.\n\t\t *\n\t\t * @method #off\n\t\t */\n\t\tthis.off = spy();\n\n\t\t/**\n\t\t * The value which will be returned by {@link module:utils/emittermixin~EmitterMixin#fire}.\n\t\t *\n\t\t * It's `undefined` by default and can be changed by an event listener:\n\t\t *\n\t\t *\t\tdataController.fire( 'getSelectedContent', ( evt ) => {\n\t\t *\t\t\t// This listener will make `dataController.fire( 'getSelectedContent' )`\n\t\t *\t\t\t// always return an empty DocumentFragment.\n\t\t *\t\t\tevt.return = new DocumentFragment();\n\t\t *\n\t\t *\t\t\t// Make sure no other listeners are executed.\n\t\t *\t\t\tevt.stop();\n\t\t *\t\t} );\n\t\t *\n\t\t * @member #return\n\t\t */\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/eventinfo.js\n// module id = null\n// module chunks = ","import eq from './eq';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\nexport default assignValue;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_assignValue.js\n// module id = null\n// module chunks = ","import assignValue from './_assignValue';\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : source[key];\n\n assignValue(object, key, newValue);\n }\n return object;\n}\n\nexport default copyObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_copyObject.js\n// module id = null\n// module chunks = ","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseProperty.js\n// module id = null\n// module chunks = ","import baseProperty from './_baseProperty';\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a\n * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n * Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\nexport default getLength;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_getLength.js\n// module id = null\n// module chunks = ","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isObject.js\n// module id = null\n// module chunks = ","import isObject from './isObject';\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\nexport default isFunction;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isFunction.js\n// module id = null\n// module chunks = ","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length,\n * else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isLength.js\n// module id = null\n// module chunks = ","import getLength from './_getLength';\nimport isFunction from './isFunction';\nimport isLength from './isLength';\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(getLength(value)) && !isFunction(value);\n}\n\nexport default isArrayLike;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isArrayLike.js\n// module id = null\n// module chunks = ","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_isIndex.js\n// module id = null\n// module chunks = ","import eq from './eq';\nimport isArrayLike from './isArrayLike';\nimport isIndex from './_isIndex';\nimport isObject from './isObject';\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\nexport default isIterateeCall;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_isIterateeCall.js\n// module id = null\n// module chunks = ","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n var length = args.length;\n switch (length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_apply.js\n// module id = null\n// module chunks = ","import isObjectLike from './isObjectLike';\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\nexport default isSymbol;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isSymbol.js\n// module id = null\n// module chunks = ","import isFunction from './isFunction';\nimport isObject from './isObject';\nimport isSymbol from './isSymbol';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = isFunction(value.valueOf) ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nexport default toNumber;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/toNumber.js\n// module id = null\n// module chunks = ","import toNumber from './toNumber';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308;\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\nexport default toFinite;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/toFinite.js\n// module id = null\n// module chunks = ","import toFinite from './toFinite';\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This function is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\nexport default toInteger;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/toInteger.js\n// module id = null\n// module chunks = ","import isIterateeCall from './_isIterateeCall';\nimport rest from './rest';\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return rest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\nexport default createAssigner;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_createAssigner.js\n// module id = null\n// module chunks = ","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_isPrototype.js\n// module id = null\n// module chunks = ","import root from './_root';\n\n/** Built-in value references. */\nvar Reflect = root.Reflect;\n\nexport default Reflect;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_Reflect.js\n// module id = null\n// module chunks = ","/**\n * Converts `iterator` to an array.\n *\n * @private\n * @param {Object} iterator The iterator to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction iteratorToArray(iterator) {\n var data,\n result = [];\n\n while (!(data = iterator.next()).done) {\n result.push(data.value);\n }\n return result;\n}\n\nexport default iteratorToArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_iteratorToArray.js\n// module id = null\n// module chunks = ","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseTimes.js\n// module id = null\n// module chunks = ","import isArrayLike from './isArrayLike';\nimport isObjectLike from './isObjectLike';\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\nexport default isArrayLikeObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isArrayLikeObject.js\n// module id = null\n// module chunks = ","import isArrayLikeObject from './isArrayLikeObject';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\nexport default isArguments;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isArguments.js\n// module id = null\n// module chunks = ","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @type {Function}\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isArray.js\n// module id = null\n// module chunks = ","import isArray from './isArray';\nimport isObjectLike from './isObjectLike';\n\n/** `Object#toString` result references. */\nvar stringTag = '[object String]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\nfunction isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);\n}\n\nexport default isString;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isString.js\n// module id = null\n// module chunks = ","import baseTimes from './_baseTimes';\nimport isArguments from './isArguments';\nimport isArray from './isArray';\nimport isLength from './isLength';\nimport isString from './isString';\n\n/**\n * Creates an array of index keys for `object` values of arrays,\n * `arguments` objects, and strings, otherwise `null` is returned.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array|null} Returns index keys, else `null`.\n */\nfunction indexKeys(object) {\n var length = object ? object.length : undefined;\n if (isLength(length) &&\n (isArray(object) || isString(object) || isArguments(object))) {\n return baseTimes(length, String);\n }\n return null;\n}\n\nexport default indexKeys;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_indexKeys.js\n// module id = null\n// module chunks = ","import baseKeysIn from './_baseKeysIn';\nimport indexKeys from './_indexKeys';\nimport isIndex from './_isIndex';\nimport isPrototype from './_isPrototype';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n var index = -1,\n isProto = isPrototype(object),\n props = baseKeysIn(object),\n propsLength = props.length,\n indexes = indexKeys(object),\n skipIndexes = !!indexes,\n result = indexes || [],\n length = result.length;\n\n while (++index < propsLength) {\n var key = props[index];\n if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&\n !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default keysIn;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/keysIn.js\n// module id = null\n// module chunks = ","import assignValue from './_assignValue';\nimport copyObject from './_copyObject';\nimport createAssigner from './_createAssigner';\nimport isArrayLike from './isArrayLike';\nimport isPrototype from './_isPrototype';\nimport keysIn from './keysIn';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */\nvar nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');\n\n/**\n * This method is like `_.assign` except that it iterates over own and\n * inherited source properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extend\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assign\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * function Bar() {\n * this.d = 4;\n * }\n *\n * Foo.prototype.c = 3;\n * Bar.prototype.e = 5;\n *\n * _.assignIn({ 'a': 1 }, new Foo, new Bar);\n * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }\n */\nvar assignIn = createAssigner(function(object, source) {\n if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keysIn(source), object);\n return;\n }\n for (var key in source) {\n assignValue(object, key, source[key]);\n }\n});\n\nexport default assignIn;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/assignIn.js\n// module id = null\n// module chunks = ","export { default } from './assignIn'\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/extend.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/text\n */\n\nimport Node from './node';\n\n/**\n * Model text node. Type of {@link module:engine/model/node~Node node} that contains {@link module:engine/model/text~Text#data text data}.\n *\n * **Important:** see {@link module:engine/model/node~Node} 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~writer 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~LivePosition live position} placed before the text node.\n */\nexport default class Text extends Node {\n\t/**\n\t * Creates a text node.\n\t *\n\t * @param {String} data Node's text.\n\t * @param {Object} [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\n\t\t/**\n\t\t * Text data contained in this text node.\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tthis.data = data || '';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget offsetSize() {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type ) {\n\t\treturn type == 'text';\n\t}\n\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\tclone() {\n\t\treturn new Text( this.data, this.getAttributes() );\n\t}\n\n\t/**\n\t * Converts `Text` instance to plain object and returns it.\n\t *\n\t * @returns {Object} `Text` instance converted to plain object.\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.data = this.data;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a `Text` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param {Object} json Plain object to be converted to `Text`.\n\t * @returns {module:engine/model/text~Text} `Text` instance created using given plain object.\n\t */\n\tstatic fromJSON( json ) {\n\t\treturn new Text( json.data, json.attributes );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/text.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/textproxy\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * `TextProxy` represents a part of {@link module:engine/model/text~Text text node}.\n *\n * Since {@link module:engine/model/position~Position positions} can be placed between characters of a text node,\n * {@link module:engine/model/range~Range ranges} may contain only parts of text nodes. When {@link module:engine/model/range~Range#getItems\n * 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 * `TextProxy` solves this issue.\n *\n * `TextProxy` has an API similar to {@link module:engine/model/text~Text Text} and allows to do most of the common tasks performed\n * on model nodes.\n *\n * **Note:** Some `TextProxy` instances may represent whole text node, not just a part of it.\n * See {@link module:engine/model/textproxy~TextProxy#isPartial}.\n *\n * **Note:** `TextProxy` is not an instance of {@link module:engine/model/node~Node node}. Keep this in mind when using it as a\n * parameter of methods.\n *\n * **Note:** `TextProxy` is a readonly interface. If you want to perform changes on model data represented by a `TextProxy`\n * use {@link module:engine/model/writer~writer model writer API}.\n *\n * **Note:** `TextProxy` 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 `TextProxy` instances. `TextProxy` instances are not refreshed when\n * model changes, so they might get invalidated. Instead, consider creating {@link module:engine/model/liveposition~LivePosition live\n * position}.\n *\n * `TextProxy` instances are created by {@link module:engine/model/treewalker~TreeWalker model tree walker}. You should not need to create\n * an instance of this class by your own.\n */\nexport default class TextProxy {\n\t/**\n\t * Creates a text proxy.\n\t *\n\t * @protected\n\t * @param {module:engine/model/text~Text} textNode Text node which part is represented by this text proxy.\n\t * @param {Number} offsetInText Offset in {@link module:engine/model/textproxy~TextProxy#textNode text node} from which the text proxy\n\t * starts.\n\t * @param {Number} length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t * @constructor\n\t */\n\tconstructor( textNode, offsetInText, length ) {\n\t\t/**\n\t\t * Text node which part is represented by this text proxy.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/text~Text}\n\t\t */\n\t\tthis.textNode = textNode;\n\n\t\tif ( offsetInText < 0 || offsetInText > textNode.offsetSize ) {\n\t\t\t/**\n\t\t\t * Given `offsetInText` value is incorrect.\n\t\t\t *\n\t\t\t * @error model-textproxy-wrong-offsetintext\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-textproxy-wrong-offsetintext: Given offsetInText value is incorrect.' );\n\t\t}\n\n\t\tif ( length < 0 || offsetInText + length > textNode.offsetSize ) {\n\t\t\t/**\n\t\t\t * Given `length` value is incorrect.\n\t\t\t *\n\t\t\t * @error model-textproxy-wrong-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-textproxy-wrong-length: Given length value is incorrect.' );\n\t\t}\n\n\t\t/**\n\t\t * Text data represented by this text proxy.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.data = textNode.data.substring( offsetInText, offsetInText + length );\n\n\t\t/**\n\t\t * Offset in {@link module:engine/model/textproxy~TextProxy#textNode text node} from which the text proxy starts.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.offsetInText = offsetInText;\n\t}\n\n\t/**\n\t * Offset at which this text proxy starts in it's parent.\n\t *\n\t * @see module:engine/model/node~Node#startOffset\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget startOffset() {\n\t\treturn this.textNode.startOffset !== null ? this.textNode.startOffset + this.offsetInText : null;\n\t}\n\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~Node#offsetSize\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget offsetSize() {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * Offset at which this text proxy ends in it's parent.\n\t *\n\t * @see module:engine/model/node~Node#endOffset\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget endOffset() {\n\t\treturn this.startOffset !== null ? this.startOffset + this.offsetSize : null;\n\t}\n\n\t/**\n\t * Flag indicating whether `TextProxy` instance covers only part of the original {@link module:engine/model/text~Text 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/model/textproxy~TextProxy#textNode textNode}\n\t * ({@link module:engine/model/textproxy~TextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t * text node size.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isPartial() {\n\t\treturn this.offsetSize !== this.textNode.offsetSize;\n\t}\n\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\t * @readonly\n\t * @type {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tget parent() {\n\t\treturn this.textNode.parent;\n\t}\n\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\t * @readonly\n\t * @type {module:engine/model/node~Node|module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.textNode.root;\n\t}\n\n\t/**\n\t * {@link module:engine/model/document~Document Document} that owns text node represented by this text proxy or `null` if the text node\n\t * has no parent or is inside a {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/document~Document|null}\n\t */\n\tget document() {\n\t\treturn this.textNode.document;\n\t}\n\n\t/**\n\t * Checks whether given model tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/model/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'textProxy';\n\t}\n\n\t/**\n\t * Gets path to this text proxy.\n\t *\n\t * @see module:engine/model/node~Node#getPath\n\t * @returns {Array.<Number>}\n\t */\n\tgetPath() {\n\t\tconst path = this.textNode.getPath();\n\n\t\tif ( path.length > 0 ) {\n\t\t\tpath[ path.length - 1 ] += this.offsetInText;\n\t\t}\n\n\t\treturn path;\n\t}\n\n\t/**\n\t * Returns ancestors array of this text proxy.\n\t *\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` this text proxy will be also included in parent's array.\n\t * @param {Boolean} [options.parentFirst=false] 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} Array with ancestors.\n\t */\n\tgetAncestors( options = { includeSelf: false, parentFirst: false } ) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Checks if this text proxy has an attribute for given key.\n\t *\n\t * @param {String} key Key of attribute to check.\n\t * @returns {Boolean} `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\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 {String} 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\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\t * @returns {Iterable.<*>}\n\t */\n\tgetAttributes() {\n\t\treturn this.textNode.getAttributes();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attribute keys.\n\t *\n\t * @returns {Iterator.<String>}\n\t */\n\tgetAttributeKeys() {\n\t\treturn this.textNode.getAttributeKeys();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/textproxy.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/nodelist\n */\n\nimport Node from './node';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Provides an interface to operate on a list of {@link module:engine/model/node~Node nodes}. `NodeList` is used internally\n * in classes like {@link module:engine/model/element~Element Element}\n * or {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.\n */\nexport default class NodeList {\n\t/**\n\t * Creates an empty node list.\n\t *\n\t * @param {Iterable.<module:engine/model/node~Node>} nodes Nodes contained in this node list.\n\t */\n\tconstructor( nodes ) {\n\t\t/**\n\t\t * Nodes contained in this node list.\n\t\t *\n\t\t * @private\n\t\t * @member {Array.<module:engine/model/node~Node>}\n\t\t */\n\t\tthis._nodes = [];\n\n\t\tif ( nodes ) {\n\t\t\tthis.insertNodes( 0, nodes );\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all nodes contained inside this node list.\n\t *\n\t * @returns {Iterator.<module:engine/model/node~Node>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._nodes[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Number of nodes contained inside this node list.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget length() {\n\t\treturn this._nodes.length;\n\t}\n\n\t/**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all nodes contained inside this node list.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget maxOffset() {\n\t\treturn this._nodes.reduce( ( sum, node ) => sum + node.offsetSize, 0 );\n\t}\n\n\t/**\n\t * Gets the node at the given index. Returns `null` if incorrect index was passed.\n\t *\n\t * @param {Number} index Index of node.\n\t * @returns {module:engine/model/node~Node|null} Node at given index.\n\t */\n\tgetNode( index ) {\n\t\treturn this._nodes[ index ] || null;\n\t}\n\n\t/**\n\t * Returns an index of the given node. Returns `null` if given node is not inside this node list.\n\t *\n\t * @param {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number|null} Child node's index.\n\t */\n\tgetNodeIndex( node ) {\n\t\tconst index = this._nodes.indexOf( node );\n\n\t\treturn index == -1 ? null : index;\n\t}\n\n\t/**\n\t * Returns the starting offset of given node. Starting offset is equal to the sum of\n\t * {module:engine/model/node~Node#offsetSize offset sizes} of all nodes that are before this node in this node list.\n\t *\n\t * @param {module:engine/model/node~Node} node Node to look for.\n\t * @returns {Number|null} Node's starting offset.\n\t */\n\tgetNodeStartOffset( node ) {\n\t\tconst index = this.getNodeIndex( node );\n\n\t\treturn index === null ? null : this._nodes.slice( 0, index ).reduce( ( sum, node ) => sum + node.offsetSize, 0 );\n\t}\n\n\t/**\n\t * Converts index to offset in node list.\n\t *\n\t * Returns starting offset of a node that is at given index. Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * `model-nodelist-index-out-of-bounds` if given index is less than `0` or more than {@link #length}.\n\t *\n\t * @param {Number} index Node's index.\n\t * @returns {Number} Node's starting offset.\n\t */\n\tindexToOffset( index ) {\n\t\tif ( index == this._nodes.length ) {\n\t\t\treturn this.maxOffset;\n\t\t}\n\n\t\tconst node = this._nodes[ index ];\n\n\t\tif ( !node ) {\n\t\t\t/**\n\t\t\t * Given index cannot be found in the node list.\n\t\t\t *\n\t\t\t * @error nodelist-index-out-of-bounds\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-nodelist-index-out-of-bounds: Given index cannot be found in the node list.' );\n\t\t}\n\n\t\treturn this.getNodeStartOffset( node );\n\t}\n\n\t/**\n\t * Converts offset in node list to index.\n\t *\n\t * Returns index of a node that occupies given offset. Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * `model-nodelist-offset-out-of-bounds` if given offset is less than `0` or more than {@link #maxOffset}.\n\t *\n\t * @param {Number} offset Offset to look for.\n\t * @returns {Number} Index of a node that occupies given offset.\n\t */\n\toffsetToIndex( offset ) {\n\t\tlet totalOffset = 0;\n\n\t\tfor ( const node of this._nodes ) {\n\t\t\tif ( offset >= totalOffset && offset < totalOffset + node.offsetSize ) {\n\t\t\t\treturn this.getNodeIndex( node );\n\t\t\t}\n\n\t\t\ttotalOffset += node.offsetSize;\n\t\t}\n\n\t\tif ( totalOffset != offset ) {\n\t\t\t/**\n\t\t\t * Given offset cannot be found in the node list.\n\t\t\t *\n\t\t\t * @error nodelist-offset-out-of-bounds\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-nodelist-offset-out-of-bounds: Given offset cannot be found in the node list.' );\n\t\t}\n\n\t\treturn this.length;\n\t}\n\n\t/**\n\t * Inserts given nodes at given index.\n\t *\n\t * @param {Number} index Index at which nodes should be inserted.\n\t * @param {Iterable.<module:engine/model/node~Node>} nodes Nodes to be inserted.\n\t */\n\tinsertNodes( index, nodes ) {\n\t\t// Validation.\n\t\tfor ( const node of nodes ) {\n\t\t\tif ( !( node instanceof Node ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to insert an object which is not a Node instance.\n\t\t\t\t *\n\t\t\t\t * @error nodelist-insertNodes-not-node\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'model-nodelist-insertNodes-not-node: Trying to insert an object which is not a Node instance.' );\n\t\t\t}\n\t\t}\n\n\t\tthis._nodes.splice( index, 0, ...nodes );\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index.\n\t *\n\t * @param {Number} indexStart Index of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/model/node~Node>} Array containing removed nodes.\n\t */\n\tremoveNodes( indexStart, howMany = 1 ) {\n\t\treturn this._nodes.splice( indexStart, howMany );\n\t}\n\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 {Array.<module:engine/model/node~Node>} `NodeList` instance converted to `Array`.\n\t */\n\ttoJSON() {\n\t\treturn this._nodes.map( node => node.toJSON() );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/nodelist.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/range\n */\n\nimport Position from './position';\nimport TreeWalker from './treewalker';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Range class. Range is iterable.\n */\nexport default class Range {\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/model/position~Position Position} instances basing on passed values.\n\t *\n\t * @param {module:engine/model/position~Position} start Start position.\n\t * @param {module:engine/model/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t */\n\tconstructor( start, end = null ) {\n\t\t/**\n\t\t * Start position.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/position~Position}\n\t\t */\n\t\tthis.start = Position.createFromPosition( start );\n\n\t\t/**\n\t\t * End position.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/position~Position}\n\t\t */\n\t\tthis.end = end ? Position.createFromPosition( end ) : Position.createFromPosition( start );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/model/item~Item items} that are in this range and returns\n\t * them together with additional information like length or {@link module:engine/model/position~Position positions},\n\t * grouped as {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t * It iterates over all {@link module:engine/model/textproxy~TextProxy text contents} that are inside the range\n\t * and all the {@link module:engine/model/element~Element}s that are entered into when iterating over this range.\n\t *\n\t * This iterator uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range\n\t * and `ignoreElementEnd` option set to `true`.\n\t *\n\t * @returns {Iterable.<module:engine/model/treewalker~TreeWalkerValue>}\n\t */\n\t* [ Symbol.iterator ]() {\n\t\tyield* new TreeWalker( { boundaries: this, ignoreElementEnd: true } );\n\t}\n\n\t/**\n\t * Returns whether the range is collapsed, that is if {@link #start} and\n\t * {@link #end} positions are equal.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this.start.isEqual( this.end );\n\t}\n\n\t/**\n\t * Returns 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~Position#parent}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isFlat() {\n\t\treturn this.start.parent === this.end.parent;\n\t}\n\n\t/**\n\t * Range root element.\n\t *\n\t * @type {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.start.root;\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link module:engine/model/position~Position position}.\n\t *\n\t * @param {module:engine/model/position~Position} position Position to check.\n\t * @returns {Boolean} `true` if given {@link module:engine/model/position~Position 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\n\t/**\n\t * Checks whether this range contains given {@link ~Range range}.\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to check.\n\t * @param {Boolean} [loose=false] 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 ~Range range} boundaries are contained by this range, `false` otherwise.\n\t */\n\tcontainsRange( otherRange, loose = false ) {\n\t\tif ( otherRange.isCollapsed ) {\n\t\t\tloose = false;\n\t\t}\n\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\n\t\treturn containsStart && containsEnd;\n\t}\n\n\t/**\n\t * Checks whether given {@link module:engine/model/item~Item} is inside this range.\n\t *\n\t * @param {module:engine/model/item~Item} item Model item to check.\n\t */\n\tcontainsItem( item ) {\n\t\tconst pos = Position.createBefore( item );\n\n\t\treturn this.containsPosition( pos ) || this.start.isEqual( pos );\n\t}\n\n\t/**\n\t * Two ranges are equal if their {@link #start} and {@link #end} positions are equal.\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to compare with.\n\t * @returns {Boolean} `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\n\t/**\n\t * Checks and returns whether this range intersects with given range.\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to compare with.\n\t * @returns {Boolean} `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\n\t/**\n\t * Computes which part(s) of this {@link ~Range range} is not a part of given {@link ~Range range}.\n\t * Returned array contains zero, one or two {@link ~Range ranges}.\n\t *\n\t * Examples:\n\t *\n\t *\t\tlet range = new Range( new Position( root, [ 2, 7 ] ), new Position( root, [ 4, 0, 1 ] ) );\n\t *\t\tlet otherRange = new Range( new Position( root, [ 1 ] ), new Position( root, [ 5 ] ) );\n\t *\t\tlet transformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has no ranges because `otherRange` contains `range`\n\t *\n\t *\t\totherRange = new Range( new Position( root, [ 1 ] ), new Position( root, [ 3 ] ) );\n\t *\t\ttransformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has one range: from [ 3 ] to [ 4, 0, 1 ]\n\t *\n\t *\t\totherRange = new Range( new Position( root, [ 3 ] ), new Position( root, [ 4 ] ) );\n\t *\t\ttransformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has two ranges: from [ 2, 7 ] to [ 3 ] and from [ 4 ] to [ 4, 0, 1 ]\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to differentiate against.\n\t * @returns {Array.<module:engine/model/range~Range>} The difference between ranges.\n\t */\n\tgetDifference( otherRange ) {\n\t\tconst ranges = [];\n\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect.\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the start to the middle of this range.\n\t\t\t\tranges.push( new Range( this.start, otherRange.start ) );\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the middle of this range to the end.\n\t\t\t\tranges.push( new Range( otherRange.end, this.end ) );\n\t\t\t}\n\t\t} else {\n\t\t\t// Ranges do not intersect, return the original range.\n\t\t\tranges.push( Range.createFromRange( this ) );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an intersection of this {@link ~Range range} and given {@link ~Range 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 *\t\tlet range = new Range( new Position( root, [ 2, 7 ] ), new Position( root, [ 4, 0, 1 ] ) );\n\t *\t\tlet otherRange = new Range( new Position( root, [ 1 ] ), new Position( root, [ 2 ] ) );\n\t *\t\tlet transformed = range.getIntersection( otherRange ); // null - ranges have no common part\n\t *\n\t *\t\totherRange = new Range( new Position( root, [ 3 ] ), new Position( root, [ 5 ] ) );\n\t *\t\ttransformed = range.getIntersection( otherRange ); // range from [ 3 ] to [ 4, 0, 1 ]\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to check for intersection.\n\t * @returns {module:engine/model/range~Range|null} 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\t// Ranges intersect, so a common range will be returned.\n\t\t\t// At most, it will be same as this range.\n\t\t\tlet commonRangeStart = this.start;\n\t\t\tlet commonRangeEnd = this.end;\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means thaNt we have to\n\t\t\t\t// shrink common range to the given range start.\n\t\t\t\tcommonRangeStart = otherRange.start;\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// shrink common range to the given range end.\n\t\t\t\tcommonRangeEnd = otherRange.end;\n\t\t\t}\n\n\t\t\treturn new Range( commonRangeStart, commonRangeEnd );\n\t\t}\n\n\t\t// Ranges do not intersect, so they do not have common part.\n\t\treturn null;\n\t}\n\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 *\t\troot root\n\t *\t\t |- element DIV DIV P2 P3 DIV\n\t *\t\t | |- element H H P1 f o o b a r H P4\n\t *\t\t | | |- \"fir[st\" fir[st lorem se]cond ipsum\n\t *\t\t | |- element P1\n\t *\t\t | | |- \"lorem\" ||\n\t *\t\t |- element P2 ||\n\t *\t\t | |- \"foo\" VV\n\t *\t\t |- element P3\n\t *\t\t | |- \"bar\" root\n\t *\t\t |- element DIV DIV [P2 P3] DIV\n\t *\t\t | |- element H H [P1] f o o b a r H P4\n\t *\t\t | | |- \"se]cond\" fir[st] lorem [se]cond ipsum\n\t *\t\t | |- element P4\n\t *\t\t | | |- \"ipsum\"\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 *\t\t( [ 0, 0, 3 ], [ 0, 0, 5 ] ) = \"st\"\n\t *\t\t( [ 0, 1 ], [ 0, 2 ] ) = element P1 (\"lorem\")\n\t *\t\t( [ 1 ], [ 3 ] ) = element P2, element P3 (\"foobar\")\n\t *\t\t( [ 3, 0, 0 ], [ 3, 0, 2 ] ) = \"se\"\n\t *\n\t * **Note:** if an {@link module:engine/model/element~Element 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.<module:engine/model/range~Range>} 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\n\t\tconst pos = Position.createFromPosition( this.start );\n\t\tlet posParent = pos.parent;\n\n\t\t// Go up.\n\t\twhile ( pos.path.length > diffAt + 1 ) {\n\t\t\tconst howMany = posParent.maxOffset - pos.offset;\n\n\t\t\tif ( howMany !== 0 ) {\n\t\t\t\tranges.push( new Range( pos, pos.getShiftedBy( howMany ) ) );\n\t\t\t}\n\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\n\t\t// Go down.\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\n\t\t\tif ( howMany !== 0 ) {\n\t\t\t\tranges.push( new Range( pos, pos.getShiftedBy( howMany ) ) );\n\t\t\t}\n\n\t\t\tpos.offset = offset;\n\t\t\tpos.path.push( 0 );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t * @param {module:engine/model/position~Position} [options.startPosition]\n\t * @param {Boolean} [options.singleCharacters=false]\n\t * @param {Boolean} [options.shallow=false]\n\t * @param {Boolean} [options.ignoreElementEnd=false]\n\t */\n\tgetWalker( options = {} ) {\n\t\toptions.boundaries = this;\n\n\t\treturn new TreeWalker( options );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/model/item~Item items} that are in this range and returns\n\t * them.\n\t *\n\t * This method uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n\t * set to `true`. However it returns only {@link module:engine/model/item~Item model items},\n\t * not {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @method getItems\n\t * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t * @returns {Iterable.<module:engine/model/item~Item>}\n\t */\n\t* getItems( options = {} ) {\n\t\toptions.boundaries = this;\n\t\toptions.ignoreElementEnd = true;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.item;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/model/position~Position positions} that are boundaries or\n\t * contained in this range.\n\t *\n\t * This method uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n\t * {@link module:engine/model/position~Position positions}, not {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t * @returns {Iterable.<module:engine/model/position~Position>}\n\t */\n\t* getPositions( options = {} ) {\n\t\toptions.boundaries = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tyield treeWalker.position;\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.nextPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Returns a range that is a result of transforming this range by given `delta`.\n\t *\n\t * **Note:** transformation may break one range into multiple ranges (e.g. 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 {module:engine/model/delta/delta~Delta} delta Delta to transform range by.\n\t * @returns {Array.<module:engine/model/range~Range>} Range which is the result of transformation.\n\t */\n\tgetTransformedByDelta( delta ) {\n\t\tconst ranges = [ Range.createFromRange( this ) ];\n\n\t\t// Operation types that a range can be transformed by.\n\t\tconst supportedTypes = new Set( [ 'insert', 'move', 'remove', 'reinsert' ] );\n\n\t\tfor ( const operation of delta.operations ) {\n\t\t\tif ( supportedTypes.has( operation.type ) ) {\n\t\t\t\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t\t\t\tconst result = ranges[ i ]._getTransformedByDocumentChange(\n\t\t\t\t\t\toperation.type,\n\t\t\t\t\t\tdelta.type,\n\t\t\t\t\t\toperation.targetPosition || operation.position,\n\t\t\t\t\t\toperation.howMany || operation.nodes.maxOffset,\n\t\t\t\t\t\toperation.sourcePosition\n\t\t\t\t\t);\n\n\t\t\t\t\tranges.splice( i, 1, ...result );\n\n\t\t\t\t\ti += result.length - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns a range that is a result of transforming this range by multiple `deltas`.\n\t *\n\t * **Note:** transformation may break one range into multiple ranges (e.g. 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 {Iterable.<module:engine/model/delta/delta~Delta>} deltas Deltas to transform the range by.\n\t * @returns {Array.<module:engine/model/range~Range>} Range which is the result of transformation.\n\t */\n\tgetTransformedByDeltas( deltas ) {\n\t\tconst ranges = [ Range.createFromRange( this ) ];\n\n\t\tfor ( const delta of deltas ) {\n\t\t\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t\t\tconst result = ranges[ i ].getTransformedByDelta( delta );\n\n\t\t\t\tranges.splice( i, 1, ...result );\n\t\t\t\ti += result.length - 1;\n\t\t\t}\n\t\t}\n\n\t\t// It may happen that a range is split into two, and then the part of second \"piece\" is moved into first\n\t\t// \"piece\". In this case we will have incorrect third range, which should not be included in the result --\n\t\t// because it is already included in the first \"piece\". In this loop we are looking for all such ranges that\n\t\t// are inside other ranges and we simply remove them.\n\t\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t\tconst range = ranges[ i ];\n\n\t\t\tfor ( let j = i + 1; j < ranges.length; j++ ) {\n\t\t\t\tconst next = ranges[ j ];\n\n\t\t\t\tif ( range.containsRange( next ) || next.containsRange( range ) || range.isEqual( next ) ) {\n\t\t\t\t\tranges.splice( j, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of the range's both ends (in which the entire range is contained).\n\t *\n\t * @returns {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor() {\n\t\treturn this.start.getCommonAncestor( this.end );\n\t}\n\n\t/**\n\t * Returns a range that is a result of transforming this range by a change in the model document.\n\t *\n\t * @protected\n\t * @param {'insert'|'move'|'remove'|'reinsert'} type Change type.\n\t * @param {String} deltaType Type of delta that introduced the change.\n\t * @param {module:engine/model/position~Position} targetPosition Position before the first changed node.\n\t * @param {Number} howMany How many nodes has been changed.\n\t * @param {module:engine/model/position~Position} sourcePosition Source position of changes.\n\t * @returns {Array.<module:engine/model/range~Range>}\n\t */\n\t_getTransformedByDocumentChange( type, deltaType, targetPosition, howMany, sourcePosition ) {\n\t\tif ( type == 'insert' ) {\n\t\t\treturn this._getTransformedByInsertion( targetPosition, howMany, false, false );\n\t\t} else {\n\t\t\tconst sourceRange = Range.createFromPositionAndShift( sourcePosition, howMany );\n\n\t\t\t// Edge case for merge delta.\n\t\t\tif (\n\t\t\t\tdeltaType == 'merge' &&\n\t\t\t\tthis.isCollapsed &&\n\t\t\t\t( this.start.isEqual( sourceRange.start ) || this.start.isEqual( sourceRange.end ) )\n\t\t\t) {\n\t\t\t\t// Collapsed range is in merged element, at the beginning or at the end of it.\n\t\t\t\t// Without fix, the range would end up in the graveyard, together with removed element.\n\t\t\t\t// <p>foo</p><p>[]bar</p> -> <p>foobar</p><p>[]</p> -> <p>foobar</p> -> <p>foo[]bar</p>\n\t\t\t\t// <p>foo</p><p>bar[]</p> -> <p>foobar</p><p>[]</p> -> <p>foobar</p> -> <p>foobar[]</p>\n\t\t\t\t//\n\t\t\t\t// In most cases, `sourceRange.start.offset` for merge delta's move operation would be 0,\n\t\t\t\t// so this formula might look overcomplicated.\n\t\t\t\t// However in some scenarios, after operational transformation, move operation might not\n\t\t\t\t// in fact start from 0 and we need to properly count new offset.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-engine/pull/1133#issuecomment-329080668.\n\t\t\t\tconst offset = this.start.offset - sourceRange.start.offset;\n\n\t\t\t\treturn [ new Range( targetPosition.getShiftedBy( offset ) ) ];\n\t\t\t}\n\t\t\t//\n\t\t\t// Edge case for split delta.\n\t\t\t//\n\t\t\tif ( deltaType == 'split' && this.isCollapsed && this.end.isEqual( sourceRange.end ) ) {\n\t\t\t\t// Collapsed range is at the end of split element.\n\t\t\t\t// Without fix, the range would end up at the end of split (old) element instead of at the end of new element.\n\t\t\t\t// That would happen because this range is not technically inside moved range. Last step below shows the fix.\n\t\t\t\t// <p>foobar[]</p> -> <p>foobar[]</p><p></p> -> <p>foo[]</p><p>bar</p> -> <p>foo</p><p>bar[]</p>\n\t\t\t\treturn [ new Range( targetPosition.getShiftedBy( howMany ) ) ];\n\t\t\t}\n\t\t\t//\n\t\t\t// Other edge cases:\n\t\t\t//\n\t\t\t// In all examples `[]` is `this` and `{}` is `sourceRange`, while `^` is move target position.\n\t\t\t//\n\t\t\t// Example:\n\t\t\t// <p>xx</p>^<w>{<p>a[b</p>}</w><p>c]d</p> --> <p>xx</p><p>a[b</p><w></w><p>c]d</p>\n\t\t\t// ^<p>xx</p><w>{<p>a[b</p>}</w><p>c]d</p> --> <p>a[b</p><p>xx</p><w></w><p>c]d</p> // Note <p>xx</p> inclusion.\n\t\t\t// <w>{<p>a[b</p>}</w>^<p>c]d</p> --> <w></w><p>a[b</p><p>c]d</p>\n\t\t\tif (\n\t\t\t\t( sourceRange.containsPosition( this.start ) || sourceRange.start.isEqual( this.start ) ) &&\n\t\t\t\tthis.containsPosition( sourceRange.end ) &&\n\t\t\t\tthis.end.isAfter( targetPosition )\n\t\t\t) {\n\t\t\t\tconst start = this.start._getCombined(\n\t\t\t\t\tsourcePosition,\n\t\t\t\t\ttargetPosition._getTransformedByDeletion( sourcePosition, howMany )\n\t\t\t\t);\n\t\t\t\tconst end = this.end._getTransformedByMove( sourcePosition, targetPosition, howMany, false, false );\n\n\t\t\t\treturn [ new Range( start, end ) ];\n\t\t\t}\n\n\t\t\t// Example:\n\t\t\t// <p>c[d</p><w>{<p>a]b</p>}</w>^<p>xx</p> --> <p>c[d</p><w></w><p>a]b</p><p>xx</p>\n\t\t\t// <p>c[d</p><w>{<p>a]b</p>}</w><p>xx</p>^ --> <p>c[d</p><w></w><p>xx</p><p>a]b</p> // Note <p>xx</p> inclusion.\n\t\t\t// <p>c[d</p>^<w>{<p>a]b</p>}</w> --> <p>c[d</p><p>a]b</p><w></w>\n\t\t\tif (\n\t\t\t\t( sourceRange.containsPosition( this.end ) || sourceRange.end.isEqual( this.end ) ) &&\n\t\t\t\tthis.containsPosition( sourceRange.start ) &&\n\t\t\t\tthis.start.isBefore( targetPosition )\n\t\t\t) {\n\t\t\t\tconst start = this.start._getTransformedByMove(\n\t\t\t\t\tsourcePosition,\n\t\t\t\t\ttargetPosition,\n\t\t\t\t\thowMany,\n\t\t\t\t\ttrue,\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t\tconst end = this.end._getCombined(\n\t\t\t\t\tsourcePosition,\n\t\t\t\t\ttargetPosition._getTransformedByDeletion( sourcePosition, howMany )\n\t\t\t\t);\n\n\t\t\t\treturn [ new Range( start, end ) ];\n\t\t\t}\n\n\t\t\treturn this._getTransformedByMove( sourcePosition, targetPosition, howMany );\n\t\t}\n\t}\n\n\t/**\n\t * Returns an array containing one or two {@link ~Range ranges} that are a result of transforming this\n\t * {@link ~Range range} by inserting `howMany` nodes at `insertPosition`. Two {@link ~Range ranges} are\n\t * returned if the insertion was inside this {@link ~Range range} and `spread` is set to `true`.\n\t *\n\t * Examples:\n\t *\n\t *\t\tlet range = new Range( new Position( root, [ 2, 7 ] ), new Position( root, [ 4, 0, 1 ] ) );\n\t *\t\tlet transformed = range._getTransformedByInsertion( new Position( root, [ 1 ] ), 2 );\n\t *\t\t// transformed array has one range from [ 4, 7 ] to [ 6, 0, 1 ]\n\t *\n\t *\t\ttransformed = range._getTransformedByInsertion( new Position( root, [ 4, 0, 0 ] ), 4 );\n\t *\t\t// transformed array has one range from [ 2, 7 ] to [ 4, 0, 5 ]\n\t *\n\t *\t\ttransformed = range._getTransformedByInsertion( new Position( root, [ 3, 2 ] ), 4 );\n\t *\t\t// transformed array has one range, which is equal to original range\n\t *\n\t *\t\ttransformed = range._getTransformedByInsertion( new Position( root, [ 3, 2 ] ), 4, true );\n\t *\t\t// transformed array has two ranges: from [ 2, 7 ] to [ 3, 2 ] and from [ 3, 6 ] to [ 4, 0, 1 ]\n\t *\n\t *\t\ttransformed = range._getTransformedByInsertion( new Position( root, [ 4, 0, 1 ] ), 4, false, false );\n\t *\t\t// transformed array has one range which is equal to original range because insertion is after the range boundary\n\t *\n\t *\t\ttransformed = range._getTransformedByInsertion( new Position( root, [ 4, 0, 1 ] ), 4, false, true );\n\t *\t\t// transformed array has one range: from [ 2, 7 ] to [ 4, 0, 5 ] because range was expanded\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} insertPosition Position where nodes are inserted.\n\t * @param {Number} howMany How many nodes are inserted.\n\t * @param {Boolean} [spread] Flag indicating whether this {~Range range} should be spread if insertion\n\t * was inside the range. Defaults to `false`.\n\t * @param {Boolean} [isSticky] Flag indicating whether insertion should expand a range if it is in a place of\n\t * range boundary. Defaults to `false`.\n\t * @returns {Array.<module:engine/model/range~Range>} Result of the transformation.\n\t */\n\t_getTransformedByInsertion( insertPosition, howMany, spread = false, isSticky = false ) {\n\t\tif ( spread && this.containsPosition( insertPosition ) ) {\n\t\t\t// Range has to be spread. The first part is from original start to the spread point.\n\t\t\t// The other part is from spread point to the original end, but transformed by\n\t\t\t// insertion to reflect insertion changes.\n\n\t\t\treturn [\n\t\t\t\tnew Range( this.start, insertPosition ),\n\t\t\t\tnew Range(\n\t\t\t\t\tinsertPosition._getTransformedByInsertion( insertPosition, howMany, true ),\n\t\t\t\t\tthis.end._getTransformedByInsertion( insertPosition, howMany, this.isCollapsed )\n\t\t\t\t)\n\t\t\t];\n\t\t} else {\n\t\t\tconst range = Range.createFromRange( this );\n\n\t\t\tconst insertBeforeStart = !isSticky;\n\t\t\tconst insertBeforeEnd = range.isCollapsed ? true : isSticky;\n\n\t\t\trange.start = range.start._getTransformedByInsertion( insertPosition, howMany, insertBeforeStart );\n\t\t\trange.end = range.end._getTransformedByInsertion( insertPosition, howMany, insertBeforeEnd );\n\n\t\t\treturn [ range ];\n\t\t}\n\t}\n\n\t/**\n\t * Returns an array containing {@link ~Range ranges} that are a result of transforming this\n\t * {@link ~Range range} by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} sourcePosition Position from which nodes are moved.\n\t * @param {module:engine/model/position~Position} targetPosition Position to where nodes are moved.\n\t * @param {Number} howMany How many nodes are moved.\n\t * @returns {Array.<module:engine/model/range~Range>} Result of the transformation.\n\t */\n\t_getTransformedByMove( sourcePosition, targetPosition, howMany ) {\n\t\tif ( this.isCollapsed ) {\n\t\t\tconst newPos = this.start._getTransformedByMove( sourcePosition, targetPosition, howMany, true, false );\n\n\t\t\treturn [ new Range( newPos ) ];\n\t\t}\n\n\t\tlet result;\n\n\t\tconst moveRange = new Range( sourcePosition, sourcePosition.getShiftedBy( howMany ) );\n\n\t\tconst differenceSet = this.getDifference( moveRange );\n\t\tlet difference = null;\n\n\t\tconst common = this.getIntersection( moveRange );\n\n\t\tif ( differenceSet.length == 1 ) {\n\t\t\t// `moveRange` and this range may intersect.\n\t\t\tdifference = new Range(\n\t\t\t\tdifferenceSet[ 0 ].start._getTransformedByDeletion( sourcePosition, howMany ),\n\t\t\t\tdifferenceSet[ 0 ].end._getTransformedByDeletion( sourcePosition, howMany )\n\t\t\t);\n\t\t} else if ( differenceSet.length == 2 ) {\n\t\t\t// `moveRange` is inside this range.\n\t\t\tdifference = new Range(\n\t\t\t\tthis.start,\n\t\t\t\tthis.end._getTransformedByDeletion( sourcePosition, howMany )\n\t\t\t);\n\t\t} // else, `moveRange` contains this range.\n\n\t\tconst insertPosition = targetPosition._getTransformedByDeletion( sourcePosition, howMany );\n\n\t\tif ( difference ) {\n\t\t\tresult = difference._getTransformedByInsertion( insertPosition, howMany, common !== null );\n\t\t} else {\n\t\t\tresult = [];\n\t\t}\n\n\t\tif ( common ) {\n\t\t\tresult.push( new Range(\n\t\t\t\tcommon.start._getCombined( moveRange.start, insertPosition ),\n\t\t\t\tcommon.end._getCombined( moveRange.start, insertPosition )\n\t\t\t) );\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Creates a new range, spreading from specified {@link module:engine/model/position~Position 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 * @param {module:engine/model/position~Position} position Beginning of the range.\n\t * @param {Number} shift How long the range should be.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tstatic createFromPositionAndShift( position, shift ) {\n\t\tconst start = position;\n\t\tconst end = position.getShiftedBy( shift );\n\n\t\treturn shift > 0 ? new this( start, end ) : new this( end, start );\n\t}\n\n\t/**\n\t * Creates a range from given parents and offsets.\n\t *\n\t * @param {module:engine/model/element~Element} startElement Start position parent element.\n\t * @param {Number} startOffset Start position offset.\n\t * @param {module:engine/model/element~Element} endElement End position parent element.\n\t * @param {Number} endOffset End position offset.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tstatic createFromParentsAndOffsets( startElement, startOffset, endElement, endOffset ) {\n\t\treturn new this(\n\t\t\tPosition.createFromParentAndOffset( startElement, startOffset ),\n\t\t\tPosition.createFromParentAndOffset( endElement, endOffset )\n\t\t);\n\t}\n\n\t/**\n\t * Creates a new instance of `Range` which is equal to passed range.\n\t *\n\t * @param {module:engine/model/range~Range} range Range to clone.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tstatic createFromRange( range ) {\n\t\treturn new this( range.start, range.end );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/model/element~Element 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 {module:engine/model/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tstatic createIn( element ) {\n\t\treturn this.createFromParentsAndOffsets( element, 0, element, element.maxOffset );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/model/item~Item model item} and ends after it.\n\t *\n\t * @param {module:engine/model/item~Item} item\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tstatic createOn( item ) {\n\t\treturn this.createFromPositionAndShift( Position.createBefore( item ), item.offsetSize );\n\t}\n\n\t/**\n\t * Creates a collapsed range at given {@link module:engine/model/position~Position position}\n\t * or on the given {@link module:engine/model/item~Item item}.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tstatic createCollapsedAt( itemOrPosition, offset ) {\n\t\tconst start = Position.createAt( itemOrPosition, offset );\n\t\tconst end = Position.createFromPosition( start );\n\n\t\treturn new Range( start, end );\n\t}\n\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 *\t\t[ ][] [ ][ ][ ][ ][] [ ] // Passed ranges, shown sorted\n\t *\t\t[ ] // The result of the function if the first range was a reference range.\n\t *\t [ ] // The result of the function if the third-to-seventh range was a reference range.\n\t *\t [ ] // The result of the function if the last range was a reference range.\n\t *\n\t * @param {Array.<module:engine/model/range~Range>} ranges Ranges to combine.\n\t * @returns {module:engine/model/range~Range} Combined range.\n\t */\n\tstatic createFromRanges( ranges ) {\n\t\tif ( ranges.length === 0 ) {\n\t\t\t/**\n\t\t\t * At least one range has to be passed to\n\t\t\t * {@link module:engine/model/range~Range.createFromRanges `Range.createFromRanges()`}.\n\t\t\t *\n\t\t\t * @error range-create-from-ranges-empty-array\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'range-create-from-ranges-empty-array: At least one range has to be passed.' );\n\t\t} else if ( ranges.length == 1 ) {\n\t\t\treturn this.createFromRange( ranges[ 0 ] );\n\t\t}\n\n\t\t// 1. Set the first range in `ranges` array as a reference range.\n\t\t// If we are going to return just a one range, one of the ranges need to be the reference one.\n\t\t// Other ranges will be stuck to that range, if possible.\n\t\tconst ref = ranges[ 0 ];\n\n\t\t// 2. Sort all the ranges so it's easier to process them.\n\t\tranges.sort( ( a, b ) => {\n\t\t\treturn a.start.isAfter( b.start ) ? 1 : -1;\n\t\t} );\n\n\t\t// 3. Check at which index the reference range is now.\n\t\tconst refIndex = ranges.indexOf( ref );\n\n\t\t// 4. At this moment we don't need the original range.\n\t\t// We are going to modify the result and we need to return a new instance of Range.\n\t\t// We have to create a copy of the reference range.\n\t\tconst result = new this( ref.start, ref.end );\n\n\t\t// 5. Ranges should be checked and glued starting from the range that is closest to the reference range.\n\t\t// Since ranges are sorted, start with the range with index that is closest to reference range index.\n\t\tfor ( let i = refIndex - 1; i >= 0; i++ ) {\n\t\t\tif ( ranges[ i ].end.isEqual( result.start ) ) {\n\t\t\t\tresult.start = Position.createFromPosition( ranges[ i ].start );\n\t\t\t} else {\n\t\t\t\t// If ranges are not starting/ending at the same position there is no point in looking further.\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// 6. Ranges should be checked and glued starting from the range that is closest to the reference range.\n\t\t// Since ranges are sorted, start with the range with index that is closest to reference range index.\n\t\tfor ( let i = refIndex + 1; i < ranges.length; i++ ) {\n\t\t\tif ( ranges[ i ].start.isEqual( result.end ) ) {\n\t\t\t\tresult.end = Position.createFromPosition( ranges[ i ].end );\n\t\t\t} else {\n\t\t\t\t// If ranges are not starting/ending at the same position there is no point in looking further.\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Creates a `Range` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param {Object} json Plain object to be converted to `Range`.\n\t * @param {module:engine/model/document~Document} doc Document object that will be range owner.\n\t * @returns {module:engine/model/element~Element} `Range` instance created using given plain object.\n\t */\n\tstatic fromJSON( json, doc ) {\n\t\treturn new this( Position.fromJSON( json.start, doc ), Position.fromJSON( json.end, doc ) );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/range.js\n// module id = null\n// module chunks = ","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n}\n\nexport default listCacheClear;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_listCacheClear.js\n// module id = null\n// module chunks = ","import eq from './eq';\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to search.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nexport default assocIndexOf;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_assocIndexOf.js\n// module id = null\n// module chunks = ","import assocIndexOf from './_assocIndexOf';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n return true;\n}\n\nexport default listCacheDelete;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_listCacheDelete.js\n// module id = null\n// module chunks = ","import assocIndexOf from './_assocIndexOf';\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nexport default listCacheGet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_listCacheGet.js\n// module id = null\n// module chunks = ","import assocIndexOf from './_assocIndexOf';\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nexport default listCacheHas;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_listCacheHas.js\n// module id = null\n// module chunks = ","import assocIndexOf from './_assocIndexOf';\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nexport default listCacheSet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_listCacheSet.js\n// module id = null\n// module chunks = ","import ListCache from './_ListCache';\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n}\n\nexport default stackClear;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_stackClear.js\n// module id = null\n// module chunks = ","/** Used to resolve the decompiled source of functions. */\nvar funcToString = Function.prototype.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to process.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_toSource.js\n// module id = null\n// module chunks = ","import isFunction from './isFunction';\nimport isHostObject from './_isHostObject';\nimport isObject from './isObject';\nimport toSource from './_toSource';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n if (!isObject(value)) {\n return false;\n }\n var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nexport default isNative;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isNative.js\n// module id = null\n// module chunks = ","import isNative from './isNative';\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = object[key];\n return isNative(value) ? value : undefined;\n}\n\nexport default getNative;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_getNative.js\n// module id = null\n// module chunks = ","import getNative from './_getNative';\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nexport default nativeCreate;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_nativeCreate.js\n// module id = null\n// module chunks = ","import nativeCreate from './_nativeCreate';\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n}\n\nexport default hashClear;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_hashClear.js\n// module id = null\n// module chunks = ","import nativeCreate from './_nativeCreate';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nexport default hashGet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_hashGet.js\n// module id = null\n// module chunks = ","import nativeCreate from './_nativeCreate';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);\n}\n\nexport default hashHas;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_hashHas.js\n// module id = null\n// module chunks = ","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n return this.has(key) && delete this.__data__[key];\n}\n\nexport default hashDelete;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_hashDelete.js\n// module id = null\n// module chunks = ","import nativeCreate from './_nativeCreate';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nexport default hashSet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_hashSet.js\n// module id = null\n// module chunks = ","import getNative from './_getNative';\nimport root from './_root';\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nexport default Map;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_Map.js\n// module id = null\n// module chunks = ","import Hash from './_Hash';\nimport ListCache from './_ListCache';\nimport Map from './_Map';\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nexport default mapCacheClear;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_mapCacheClear.js\n// module id = null\n// module chunks = ","import isKeyable from './_isKeyable';\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nexport default getMapData;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_getMapData.js\n// module id = null\n// module chunks = ","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_isKeyable.js\n// module id = null\n// module chunks = ","import getMapData from './_getMapData';\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n return getMapData(this, key)['delete'](key);\n}\n\nexport default mapCacheDelete;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_mapCacheDelete.js\n// module id = null\n// module chunks = ","import getMapData from './_getMapData';\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nexport default mapCacheGet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_mapCacheGet.js\n// module id = null\n// module chunks = ","import getMapData from './_getMapData';\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nexport default mapCacheHas;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_mapCacheHas.js\n// module id = null\n// module chunks = ","import getMapData from './_getMapData';\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n getMapData(this, key).set(key, value);\n return this;\n}\n\nexport default mapCacheSet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_mapCacheSet.js\n// module id = null\n// module chunks = ","import ListCache from './_ListCache';\nimport MapCache from './_MapCache';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var cache = this.__data__;\n if (cache instanceof ListCache && cache.__data__.length == LARGE_ARRAY_SIZE) {\n cache = this.__data__ = new MapCache(cache.__data__);\n }\n cache.set(key, value);\n return this;\n}\n\nexport default stackSet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_stackSet.js\n// module id = null\n// module chunks = ","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n return this.__data__['delete'](key);\n}\n\nexport default stackDelete;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_stackDelete.js\n// module id = null\n// module chunks = ","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_stackGet.js\n// module id = null\n// module chunks = ","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_stackHas.js\n// module id = null\n// module chunks = ","/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\nexport default arrayEach;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_arrayEach.js\n// module id = null\n// module chunks = ","import getPrototype from './_getPrototype';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.has` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHas(object, key) {\n // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,\n // that are composed entirely of index properties, return `false` for\n // `hasOwnProperty` checks of them.\n return hasOwnProperty.call(object, key) ||\n (typeof object == 'object' && key in object && getPrototype(object) === null);\n}\n\nexport default baseHas;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseHas.js\n// module id = null\n// module chunks = ","/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = Object.keys;\n\n/**\n * The base implementation of `_.keys` which doesn't skip the constructor\n * property of prototypes or treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n return nativeKeys(Object(object));\n}\n\nexport default baseKeys;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseKeys.js\n// module id = null\n// module chunks = ","import baseHas from './_baseHas';\nimport baseKeys from './_baseKeys';\nimport indexKeys from './_indexKeys';\nimport isArrayLike from './isArrayLike';\nimport isIndex from './_isIndex';\nimport isPrototype from './_isPrototype';\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n var isProto = isPrototype(object);\n if (!(isProto || isArrayLike(object))) {\n return baseKeys(object);\n }\n var indexes = indexKeys(object),\n skipIndexes = !!indexes,\n result = indexes || [],\n length = result.length;\n\n for (var key in object) {\n if (baseHas(object, key) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length))) &&\n !(isProto && key == 'constructor')) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default keys;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/keys.js\n// module id = null\n// module chunks = ","import copyObject from './_copyObject';\nimport keys from './keys';\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\nexport default baseAssign;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseAssign.js\n// module id = null\n// module chunks = ","/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var result = new buffer.constructor(buffer.length);\n buffer.copy(result);\n return result;\n}\n\nexport default cloneBuffer;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cloneBuffer.js\n// module id = null\n// module chunks = ","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_copyArray.js\n// module id = null\n// module chunks = ","import copyObject from './_copyObject';\nimport getSymbols from './_getSymbols';\n\n/**\n * Copies own symbol properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\nexport default copySymbols;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_copySymbols.js\n// module id = null\n// module chunks = ","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_arrayPush.js\n// module id = null\n// module chunks = ","import arrayPush from './_arrayPush';\nimport isArray from './isArray';\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nexport default baseGetAllKeys;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseGetAllKeys.js\n// module id = null\n// module chunks = ","import baseGetAllKeys from './_baseGetAllKeys';\nimport getSymbols from './_getSymbols';\nimport keys from './keys';\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nexport default getAllKeys;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_getAllKeys.js\n// module id = null\n// module chunks = ","import getNative from './_getNative';\nimport root from './_root';\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nexport default DataView;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_DataView.js\n// module id = null\n// module chunks = ","import getNative from './_getNative';\nimport root from './_root';\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nexport default Promise;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_Promise.js\n// module id = null\n// module chunks = ","import getNative from './_getNative';\nimport root from './_root';\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nexport default Set;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_Set.js\n// module id = null\n// module chunks = ","import getNative from './_getNative';\nimport root from './_root';\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nexport default WeakMap;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_WeakMap.js\n// module id = null\n// module chunks = ","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\nexport default initCloneArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_initCloneArray.js\n// module id = null\n// module chunks = ","import root from './_root';\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nexport default Uint8Array;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_Uint8Array.js\n// module id = null\n// module chunks = ","import Uint8Array from './_Uint8Array';\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nexport default cloneArrayBuffer;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cloneArrayBuffer.js\n// module id = null\n// module chunks = ","import cloneArrayBuffer from './_cloneArrayBuffer';\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nexport default cloneDataView;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cloneDataView.js\n// module id = null\n// module chunks = ","/**\n * Adds the key-value `pair` to `map`.\n *\n * @private\n * @param {Object} map The map to modify.\n * @param {Array} pair The key-value pair to add.\n * @returns {Object} Returns `map`.\n */\nfunction addMapEntry(map, pair) {\n // Don't return `Map#set` because it doesn't return the map instance in IE 11.\n map.set(pair[0], pair[1]);\n return map;\n}\n\nexport default addMapEntry;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_addMapEntry.js\n// module id = null\n// module chunks = ","/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array.length;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n}\n\nexport default arrayReduce;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_arrayReduce.js\n// module id = null\n// module chunks = ","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_mapToArray.js\n// module id = null\n// module chunks = ","import addMapEntry from './_addMapEntry';\nimport arrayReduce from './_arrayReduce';\nimport mapToArray from './_mapToArray';\n\n/**\n * Creates a clone of `map`.\n *\n * @private\n * @param {Object} map The map to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned map.\n */\nfunction cloneMap(map, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);\n return arrayReduce(array, addMapEntry, new map.constructor);\n}\n\nexport default cloneMap;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cloneMap.js\n// module id = null\n// module chunks = ","/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\nexport default cloneRegExp;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cloneRegExp.js\n// module id = null\n// module chunks = ","/**\n * Adds `value` to `set`.\n *\n * @private\n * @param {Object} set The set to modify.\n * @param {*} value The value to add.\n * @returns {Object} Returns `set`.\n */\nfunction addSetEntry(set, value) {\n set.add(value);\n return set;\n}\n\nexport default addSetEntry;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_addSetEntry.js\n// module id = null\n// module chunks = ","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_setToArray.js\n// module id = null\n// module chunks = ","import addSetEntry from './_addSetEntry';\nimport arrayReduce from './_arrayReduce';\nimport setToArray from './_setToArray';\n\n/**\n * Creates a clone of `set`.\n *\n * @private\n * @param {Object} set The set to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned set.\n */\nfunction cloneSet(set, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);\n return arrayReduce(array, addSetEntry, new set.constructor);\n}\n\nexport default cloneSet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cloneSet.js\n// module id = null\n// module chunks = ","import root from './_root';\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nexport default Symbol;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_Symbol.js\n// module id = null\n// module chunks = ","import Symbol from './_Symbol';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nexport default cloneSymbol;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cloneSymbol.js\n// module id = null\n// module chunks = ","import cloneArrayBuffer from './_cloneArrayBuffer';\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nexport default cloneTypedArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cloneTypedArray.js\n// module id = null\n// module chunks = ","import cloneArrayBuffer from './_cloneArrayBuffer';\nimport cloneDataView from './_cloneDataView';\nimport cloneMap from './_cloneMap';\nimport cloneRegExp from './_cloneRegExp';\nimport cloneSet from './_cloneSet';\nimport cloneSymbol from './_cloneSymbol';\nimport cloneTypedArray from './_cloneTypedArray';\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, cloneFunc, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return cloneMap(object, isDeep, cloneFunc);\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return cloneSet(object, isDeep, cloneFunc);\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\nexport default initCloneByTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_initCloneByTag.js\n// module id = null\n// module chunks = ","import isObject from './isObject';\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nfunction baseCreate(proto) {\n return isObject(proto) ? objectCreate(proto) : {};\n}\n\nexport default baseCreate;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseCreate.js\n// module id = null\n// module chunks = ","import baseCreate from './_baseCreate';\nimport getPrototype from './_getPrototype';\nimport isPrototype from './_isPrototype';\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\nexport default initCloneObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_initCloneObject.js\n// module id = null\n// module chunks = ","import baseClone from './_baseClone';\n\n/**\n * Creates a shallow clone of `value`.\n *\n * **Note:** This method is loosely based on the\n * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n * and supports cloning arrays, array buffers, booleans, date objects, maps,\n * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n * arrays. The own enumerable properties of `arguments` objects are cloned\n * as plain objects. An empty object is returned for uncloneable values such\n * as error objects, functions, DOM nodes, and WeakMaps.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to clone.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeep\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var shallow = _.clone(objects);\n * console.log(shallow[0] === objects[0]);\n * // => true\n */\nfunction clone(value) {\n return baseClone(value, false, true);\n}\n\nexport default clone;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/clone.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/node\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport clone from '@ckeditor/ckeditor5-utils/src/lib/lodash/clone';\n\n/**\n * Abstract tree view node class.\n *\n * @abstract\n */\nexport default class Node {\n\t/**\n\t * Creates a tree view node.\n\t *\n\t * This is an abstract class, so this constructor should not be used directly.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Parent element. Null by default. Set by {@link module:engine/view/element~Element#insertChildren}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|null}\n\t\t */\n\t\tthis.parent = null;\n\t}\n\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\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget index() {\n\t\tlet pos;\n\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// No parent or child doesn't exist in parent's children.\n\t\tif ( ( pos = this.parent.getChildIndex( this ) ) == -1 ) {\n\t\t\t/**\n\t\t\t * The node's parent does not contain this node. It means that the document tree is corrupted.\n\t\t\t *\n\t\t\t * @error view-node-not-found-in-parent\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-node-not-found-in-parent: The node\\'s parent does not contain this node.' );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Node's next sibling, or `null` if it is the last child.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|null}\n\t */\n\tget nextSibling() {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent.getChild( index + 1 ) ) || null;\n\t}\n\n\t/**\n\t * Node's previous sibling, or `null` if it is the first child.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|null}\n\t */\n\tget previousSibling() {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent.getChild( index - 1 ) ) || null;\n\t}\n\n\t/**\n\t * Top-most ancestor of the node. If the node has no parent it is the root itself.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\tlet root = this; // eslint-disable-line consistent-this\n\n\t\twhile ( root.parent ) {\n\t\t\troot = root.parent;\n\t\t}\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * {@link module:engine/view/document~Document View document} that owns this node, or `null` if the node is inside\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/document~Document|null}\n\t */\n\tget document() {\n\t\t// Parent might be Node, null or DocumentFragment.\n\t\tif ( this.parent instanceof Node ) {\n\t\t\treturn this.parent.document;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Returns ancestors array of this node.\n\t *\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` this node will be also included in parent's array.\n\t * @param {Boolean} [options.parentFirst=false] 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} Array with ancestors.\n\t */\n\tgetAncestors( options = { includeSelf: false, parentFirst: false } ) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/element~Element} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both nodes.\n\t *\n\t * @param {module:engine/view/node~Node} node The second node.\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] 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 * @returns {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor( node, options = {} ) {\n\t\tconst ancestorsA = this.getAncestors( options );\n\t\tconst ancestorsB = node.getAncestors( options );\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Removes node from parent.\n\t */\n\tremove() {\n\t\tthis.parent.removeChildren( this.index );\n\t}\n\n\t/**\n\t * @param {module:engine/view/document~ChangeType} type Type of the change.\n\t * @param {module:engine/view/node~Node} node Changed node.\n\t * @fires change\n\t */\n\t_fireChange( type, node ) {\n\t\tthis.fire( 'change:' + type, node );\n\n\t\tif ( this.parent ) {\n\t\t\tthis.parent._fireChange( type, node );\n\t\t}\n\t}\n\n\t/**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @returns {Object} Clone of this object with the parent property removed.\n\t */\n\ttoJSON() {\n\t\tconst json = clone( this );\n\n\t\t// Due to circular references we need to remove parent reference.\n\t\tdelete json.parent;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Clones this node.\n\t *\n\t * @method #clone\n\t * @returns {module:engine/view/node~Node} Clone of this node.\n\t */\n\n\t/**\n\t * Checks if provided node is similar to this node.\n\t *\n\t * @method #isSimilar\n\t * @returns {Boolean} True if nodes are similar.\n\t */\n\n\t/**\n\t * Checks whether given view tree object is of given type.\n\t *\n\t * This method is useful when processing view tree objects that are of unknown type. For example, a function\n\t * may return {@link module:engine/view/documentfragment~DocumentFragment} or {@link module:engine/view/node~Node}\n\t * that can be either text node or element. This method can be used to check what kind of object is returned.\n\t *\n\t *\t\tobj.is( 'node' ); // true for any node, false for document fragment\n\t *\t\tobj.is( 'documentFragment' ); // true for document fragment, false for any node\n\t *\t\tobj.is( 'element' ); // true for any element, false for text node or document fragment\n\t *\t\tobj.is( 'element', 'p' ); // true only for element which name is 'p'\n\t *\t\tobj.is( 'p' ); // shortcut for obj.is( 'element', 'p' )\n\t *\t\tobj.is( 'text' ); // true for text node, false for element and document fragment\n\t *\n\t * @method #is\n\t * @param {'element'|'containerElement'|'attributeElement'|'emptyElement'|'uiElement'|\n\t * 'rootElement'|'documentFragment'|'text'|'textProxy'} type\n\t * @returns {Boolean}\n\t */\n}\n\n/**\n * Fired when list of {@link module:engine/view/element~Element elements} children changes.\n *\n * Change event is bubbled it is fired on all ancestors.\n *\n * @event change:children\n * @param {module:engine/view/node~Node} changedNode\n */\n\n/**\n * Fired when list of {@link module:engine/view/element~Element elements} attributes changes.\n *\n * Change event is bubbled it is fired on all ancestors.\n *\n * @event change:attributes\n * @param {module:engine/view/node~Node} changedNode\n */\n\n/**\n * Fired when {@link module:engine/view/text~Text text nodes} data changes.\n *\n * Change event is bubbled it is fired on all ancestors.\n *\n * @event change:text\n * @param {module:engine/view/node~Node} changedNode\n */\n\n/**\n * @event change\n */\n\nmix( Node, EmitterMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/node.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/text\n */\n\nimport Node from './node';\n\n/**\n * Tree view text node.\n *\n * @extends module:engine/view/node~Node\n */\nexport default class Text extends Node {\n\t/**\n\t * Creates a tree view text node.\n\t *\n\t * @param {String} data Text.\n\t */\n\tconstructor( data ) {\n\t\tsuper();\n\n\t\t/**\n\t\t * The text content.\n\t\t *\n\t\t * Setting the data fires the {@link module:engine/view/node~Node#event:change:text change event}.\n\t\t *\n\t\t * @private\n\t\t * @member {String} module:engine/view/text~Text#_data\n\t\t */\n\t\tthis._data = data;\n\t}\n\n\t/**\n\t * Clones this node.\n\t *\n\t * @returns {module:engine/view/text~Text} Text node that is a clone of this node.\n\t */\n\tclone() {\n\t\treturn new Text( this.data );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type ) {\n\t\treturn type == 'text';\n\t}\n\n\t/**\n\t * The text content.\n\t *\n\t * Setting the data fires the {@link module:engine/view/node~Node#event:change:text change event}.\n\t */\n\tget data() {\n\t\treturn this._data;\n\t}\n\n\tset data( data ) {\n\t\tthis._fireChange( 'text', this );\n\n\t\tthis._data = data;\n\t}\n\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 {module:engine/view/text~Text} otherNode Node to check if it is same as this node.\n\t * @returns {Boolean}\n\t */\n\tisSimilar( otherNode ) {\n\t\tif ( !( otherNode instanceof Text ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this === otherNode || this.data === otherNode.data;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/text.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/treewalker\n */\n\nimport Element from './element';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport Position from './position';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */\nexport default class TreeWalker {\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 * @constructor\n\t * @param {Object} options Object with configuration.\n\t * @param {module:engine/view/range~Range} [options.boundaries=null] Range to define boundaries of the iterator.\n\t * @param {module:engine/view/position~Position} [options.startPosition] Starting position.\n\t * @param {'forward'|'backward'} [options.direction='forward'] Walking direction.\n\t * @param {Boolean} [options.singleCharacters=false] Flag indicating whether all characters from\n\t * {@link module:engine/view/text~Text} should be returned as one {@link module:engine/view/text~Text} (`false`) ore one by one as\n\t * {@link module:engine/view/textproxy~TextProxy} (`true`).\n\t * @param {Boolean} [options.shallow=false] Flag indicating whether iterator should enter elements or not. If the\n\t * iterator is shallow child nodes of any iterated node will not be returned along with `elementEnd` tag.\n\t * @param {Boolean} [options.ignoreElementEnd=false] Flag indicating whether iterator should ignore `elementEnd`\n\t * tags. If the option is true walker will not return a parent node of start position. If this option is `true`\n\t * each {@link module:engine/view/element~Element} will be returned once, while if the option is `false` they might be returned\n\t * twice: for `'elementStart'` and `'elementEnd'`.\n\t */\n\tconstructor( options = {} ) {\n\t\tif ( !options.boundaries && !options.startPosition ) {\n\t\t\t/**\n\t\t\t * Neither boundaries nor starting position have been defined.\n\t\t\t *\n\t\t\t * @error view-tree-walker-no-start-position\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-tree-walker-no-start-position: Neither boundaries nor starting position have been defined.' );\n\t\t}\n\n\t\tif ( options.direction && options.direction != 'forward' && options.direction != 'backward' ) {\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-tree-walker-unknown-direction: Only `backward` and `forward` direction allowed.',\n\t\t\t\t{ direction: options.direction }\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Iterator boundaries.\n\t\t *\n\t\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t\t * on the start of boundary, then `{ done: true }` is returned.\n\t\t *\n\t\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/range~Range} module:engine/view/treewalker~TreeWalker#boundaries\n\t\t */\n\t\tthis.boundaries = options.boundaries || null;\n\n\t\t/**\n\t\t * Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t\t * `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/position~Position} module:engine/view/treewalker~TreeWalker#position\n\t\t */\n\t\tif ( options.startPosition ) {\n\t\t\tthis.position = Position.createFromPosition( options.startPosition );\n\t\t} else {\n\t\t\tthis.position = Position.createFromPosition( options.boundaries[ options.direction == 'backward' ? 'end' : 'start' ] );\n\t\t}\n\n\t\t/**\n\t\t * Walking direction. Defaults `'forward'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'backward'|'forward'} module:engine/view/treewalker~TreeWalker#direction\n\t\t */\n\t\tthis.direction = options.direction || 'forward';\n\n\t\t/**\n\t\t * Flag indicating whether all characters from {@link module:engine/view/text~Text} should be returned as one\n\t\t * {@link module:engine/view/text~Text} or one by one as {@link module:engine/view/textproxy~TextProxy}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#singleCharacters\n\t\t */\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t\t * iterated node will not be returned along with `elementEnd` tag.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#shallow\n\t\t */\n\t\tthis.shallow = !!options.shallow;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should ignore `elementEnd` tags. If set to `true`, walker will not\n\t\t * return a parent node of the start position. Each {@link module:engine/view/element~Element} will be returned once.\n\t\t * When set to `false` each element might be returned twice: for `'elementStart'` and `'elementEnd'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#ignoreElementEnd\n\t\t */\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\n\t\t/**\n\t\t * Start boundary parent.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/node~Node} module:engine/view/treewalker~TreeWalker#_boundaryStartParent\n\t\t */\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\n\t\t/**\n\t\t * End boundary parent.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/node~Node} module:engine/view/treewalker~TreeWalker#_boundaryEndParent\n\t\t */\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\t}\n\n\t/**\n\t * Iterator interface.\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this;\n\t}\n\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 * \t\twalker.skip( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t * \t\twalker.skip( value => true ); // Move the position to the end: <p>{}foo</p> -> <p>foo</p>[]\n\t * \t\twalker.skip( value => false ); // Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} 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;\n\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\n\t\t\t( { done, value } = this.next() );\n\t\t} while ( !done && skip( value ) );\n\n\t\tif ( !done ) {\n\t\t\tthis.position = prevPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Iterator interface method.\n\t * Detects walking direction and makes step forward or backward.\n\t *\n\t * @returns {Object} Object implementing iterator interface, returning information about taken step.\n\t */\n\tnext() {\n\t\tif ( this.direction == 'forward' ) {\n\t\t\treturn this._next();\n\t\t} else {\n\t\t\treturn this._previous();\n\t\t}\n\t}\n\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 * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done `true` if iterator is done, `false` otherwise.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_next() {\n\t\tlet position = Position.createFromPosition( this.position );\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\n\t\t// We are at the end of the root.\n\t\tif ( parent.parent === null && position.offset === parent.childCount ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Get node just after current position.\n\t\tlet node;\n\n\t\t// Text is a specific parent because it contains string instead of child nodes.\n\t\tif ( parent instanceof Text ) {\n\t\t\tif ( position.isAtEnd ) {\n\t\t\t\t// Prevent returning \"elementEnd\" for Text node. Skip that value and return the next walker step.\n\t\t\t\tthis.position = Position.createAfter( parent );\n\n\t\t\t\treturn this._next();\n\t\t\t}\n\n\t\t\tnode = parent.data[ position.offset ];\n\t\t} else {\n\t\t\tnode = parent.getChild( position.offset );\n\t\t}\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition = new Position( node, 0 );\n\t\t\t} else {\n\t\t\t\tposition.offset++;\n\t\t\t}\n\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t} else if ( node instanceof Text ) {\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tposition = new Position( node, 0 );\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._next();\n\t\t\t} else {\n\t\t\t\tlet charactersCount = node.data.length;\n\t\t\t\tlet item = node;\n\n\t\t\t\t// If text stick out of walker range, we need to cut it and wrap by TextProxy.\n\t\t\t\tif ( node == this._boundaryEndParent ) {\n\t\t\t\t\tcharactersCount = this.boundaries.end.offset;\n\t\t\t\t\titem = new TextProxy( node, 0, charactersCount );\n\t\t\t\t\tposition = Position.createAfter( item );\n\t\t\t\t} else {\n\t\t\t\t\t// If not just keep moving forward.\n\t\t\t\t\tposition.offset++;\n\t\t\t\t}\n\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t\t}\n\t\t} else if ( typeof node == 'string' ) {\n\t\t\tlet textLength;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\ttextLength = 1;\n\t\t\t} else {\n\t\t\t\t// Check if text stick out of walker range.\n\t\t\t\tconst endOffset = parent === this._boundaryEndParent ? this.boundaries.end.offset : parent.data.length;\n\n\t\t\t\ttextLength = endOffset - position.offset;\n\t\t\t}\n\n\t\t\tconst textProxy = new TextProxy( parent, position.offset, textLength );\n\n\t\t\tposition.offset += textLength;\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', textProxy, previousPosition, position, textLength );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the end of current `parent`.\n\t\t\tposition = Position.createAfter( parent );\n\t\t\tthis.position = position;\n\n\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\treturn this._next();\n\t\t\t} else {\n\t\t\t\treturn this._formatReturnValue( 'elementEnd', parent, previousPosition, position );\n\t\t\t}\n\t\t}\n\t}\n\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 * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done True if iterator is done.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_previous() {\n\t\tlet position = Position.createFromPosition( this.position );\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\n\t\t// We are at the beginning of the root.\n\t\tif ( parent.parent === null && position.offset === 0 ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Get node just before current position.\n\t\tlet node;\n\n\t\t// Text {@link module:engine/view/text~Text} element is a specific parent because contains string instead of child nodes.\n\t\tif ( parent instanceof Text ) {\n\t\t\tif ( position.isAtStart ) {\n\t\t\t\t// Prevent returning \"elementStart\" for Text node. Skip that value and return the next walker step.\n\t\t\t\tthis.position = Position.createBefore( parent );\n\n\t\t\t\treturn this._previous();\n\t\t\t}\n\n\t\t\tnode = parent.data[ position.offset - 1 ];\n\t\t} else {\n\t\t\tnode = parent.getChild( position.offset - 1 );\n\t\t}\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition = new Position( node, node.childCount );\n\t\t\t\tthis.position = position;\n\n\t\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\t\treturn this._previous();\n\t\t\t\t} else {\n\t\t\t\t\treturn this._formatReturnValue( 'elementEnd', node, previousPosition, position );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tposition.offset--;\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t\t}\n\t\t} else if ( node instanceof Text ) {\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tposition = new Position( node, node.data.length );\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._previous();\n\t\t\t} else {\n\t\t\t\tlet charactersCount = node.data.length;\n\t\t\t\tlet item = node;\n\n\t\t\t\t// If text stick out of walker range, we need to cut it and wrap by TextProxy.\n\t\t\t\tif ( node == this._boundaryStartParent ) {\n\t\t\t\t\tconst offset = this.boundaries.start.offset;\n\n\t\t\t\t\titem = new TextProxy( node, offset, node.data.length - offset );\n\t\t\t\t\tcharactersCount = item.data.length;\n\t\t\t\t\tposition = Position.createBefore( item );\n\t\t\t\t} else {\n\t\t\t\t\t// If not just keep moving backward.\n\t\t\t\t\tposition.offset--;\n\t\t\t\t}\n\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t\t}\n\t\t} else if ( typeof node == 'string' ) {\n\t\t\tlet textLength;\n\n\t\t\tif ( !this.singleCharacters ) {\n\t\t\t\t// Check if text stick out of walker range.\n\t\t\t\tconst startOffset = parent === this._boundaryStartParent ? this.boundaries.start.offset : 0;\n\n\t\t\t\ttextLength = position.offset - startOffset;\n\t\t\t} else {\n\t\t\t\ttextLength = 1;\n\t\t\t}\n\n\t\t\tposition.offset -= textLength;\n\n\t\t\tconst textProxy = new TextProxy( parent, position.offset, textLength );\n\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', textProxy, previousPosition, position, textLength );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the beginning of current `parent`.\n\t\t\tposition = Position.createBefore( parent );\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'elementStart', parent, previousPosition, position, 1 );\n\t\t}\n\t}\n\n\t/**\n\t * Format returned data and adjust `previousPosition` and `nextPosition` if reach the bound of the {@link module:engine/view/text~Text}.\n\t *\n\t * @private\n\t * @param {module:engine/view/treewalker~TreeWalkerValueType} type Type of step.\n\t * @param {module:engine/view/item~Item} item Item between old and new position.\n\t * @param {module:engine/view/position~Position} previousPosition Previous position of iterator.\n\t * @param {module:engine/view/position~Position} nextPosition Next position of iterator.\n\t * @param {Number} [length] Length of the item.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue}\n\t */\n\t_formatReturnValue( type, item, previousPosition, nextPosition, length ) {\n\t\t// Text is a specific parent, because contains string instead of children.\n\t\t// Walker doesn't enter to the Text except situations when walker is iterating over every single character,\n\t\t// or the bound starts/ends inside the Text. So when the position is at the beginning or at the end of the Text\n\t\t// we move it just before or just after Text.\n\t\tif ( item instanceof TextProxy ) {\n\t\t\t// Position is at the end of Text.\n\t\t\tif ( item.offsetInText + item.data.length == item.textNode.data.length ) {\n\t\t\t\tif ( this.direction == 'forward' && !( this.boundaries && this.boundaries.end.isEqual( this.position ) ) ) {\n\t\t\t\t\tnextPosition = Position.createAfter( item.textNode );\n\t\t\t\t\t// When we change nextPosition of returned value we need also update walker current position.\n\t\t\t\t\tthis.position = nextPosition;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousPosition = Position.createAfter( item.textNode );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Position is at the begining ot the text.\n\t\t\tif ( item.offsetInText === 0 ) {\n\t\t\t\tif ( this.direction == 'backward' && !( this.boundaries && this.boundaries.start.isEqual( this.position ) ) ) {\n\t\t\t\t\tnextPosition = Position.createBefore( item.textNode );\n\t\t\t\t\t// When we change nextPosition of returned value we need also update walker current position.\n\t\t\t\t\tthis.position = nextPosition;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousPosition = Position.createBefore( item.textNode );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\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 * Type of the step made by {@link module:engine/view/treewalker~TreeWalker}.\n * Possible values: `'elementStart'` if walker is at the beginning of a node, `'elementEnd'` if walker is at the end\n * of node, or `'text'` if walker traversed over single and multiple characters.\n * For {@link module:engine/view/text~Text} `elementStart` and `elementEnd` is not returned.\n *\n * @typedef {String} module:engine/view/treewalker~TreeWalkerValueType\n */\n\n/**\n * Object returned by {@link module:engine/view/treewalker~TreeWalker} when traversing tree view.\n *\n * @typedef {Object} module:engine/view/treewalker~TreeWalkerValue\n * @property {module:engine/view/treewalker~TreeWalkerValueType} type\n * @property {module:engine/view/item~Item} item Item between old and new positions of {@link module:engine/view/treewalker~TreeWalker}.\n * @property {module:engine/view/position~Position} previousPosition Previous position of the iterator.\n * * Forward iteration: For `'elementEnd'` it is the last position inside the element. For all other types it is the\n * position before the item. Note that it is more efficient to use this position then calculate the position before\n * the node using {@link module:engine/view/position~Position.createBefore}.\n * * Backward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after item.\n * * If the position is at the beginning or at the end of the {@link module:engine/view/text~Text} it is always moved from the\n * inside of the Text to its parent just before or just after Text.\n * @property {module:engine/view/position~Position} nextPosition Next position of the iterator.\n * * Forward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after the item.\n * * Backward iteration: For `'elementEnd'` it is last position inside element. For all other types it is the position\n * before the item.\n * * If the position is at the beginning or at the end of the {@link module:engine/view/text~Text} it is always moved from the\n * inside of the Text to its parent just before or just after Text.\n * @property {Number} [length] Length of the item. For `'elementStart'` it is 1. For `'text'` it is\n * the length of the text. For `'elementEnd'` it is undefined.\n */\n\n/**\n * Tree walking directions.\n *\n * @typedef {'forward'|'backward'} module:engine/view/treewalker~TreeWalkerDirection\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/treewalker.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/position\n */\n\nimport TreeWalker from './treewalker';\n\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport EditableElement from './editableelement';\n\n/**\n * Position in the tree. Position is always located before or after a node.\n */\nexport default class Position {\n\t/**\n\t * Creates a position.\n\t *\n\t * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} parent Position parent.\n\t * @param {Number} offset Position offset.\n\t */\n\tconstructor( parent, offset ) {\n\t\t/**\n\t\t * Position parent.\n\t\t *\n\t\t * @member {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment}\n\t\t * module:engine/view/position~Position#parent\n\t\t */\n\t\tthis.parent = parent;\n\n\t\t/**\n\t\t * Position offset.\n\t\t *\n\t\t * @member {Number} module:engine/view/position~Position#offset\n\t\t */\n\t\tthis.offset = offset;\n\t}\n\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\t * @readonly\n\t * @type {module:engine/view/node~Node|null}\n\t */\n\tget nodeAfter() {\n\t\tif ( this.parent.is( 'text' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.parent.getChild( this.offset ) || null;\n\t}\n\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\t * @readonly\n\t * @type {module:engine/view/node~Node|null}\n\t */\n\tget nodeBefore() {\n\t\tif ( this.parent.is( 'text' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.parent.getChild( this.offset - 1 ) || null;\n\t}\n\n\t/**\n\t * Is `true` if position is at the beginning of its {@link module:engine/view/position~Position#parent parent}, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isAtStart() {\n\t\treturn this.offset === 0;\n\t}\n\n\t/**\n\t * Is `true` if position is at the end of its {@link module:engine/view/position~Position#parent parent}, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isAtEnd() {\n\t\tconst endOffset = this.parent.is( 'text' ) ? this.parent.data.length : this.parent.childCount;\n\n\t\treturn this.offset === endOffset;\n\t}\n\n\t/**\n\t * Position's root, that is the root of the position's parent element.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.parent.root;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this position, or `null` if\n\t * position is not inside an editable element.\n\t *\n\t * @type {module:engine/view/editableelement~EditableElement|null}\n\t */\n\tget editableElement() {\n\t\tlet editable = this.parent;\n\n\t\twhile ( !( editable instanceof EditableElement ) ) {\n\t\t\tif ( editable.parent ) {\n\t\t\t\teditable = editable.parent;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn editable;\n\t}\n\n\t/**\n\t * Returns a new instance of Position with offset incremented by `shift` value.\n\t *\n\t * @param {Number} shift How position offset should get changed. Accepts negative values.\n\t * @returns {module:engine/view/position~Position} Shifted position.\n\t */\n\tgetShiftedBy( shift ) {\n\t\tconst shifted = Position.createFromPosition( this );\n\n\t\tconst offset = shifted.offset + shift;\n\t\tshifted.offset = offset < 0 ? 0 : offset;\n\n\t\treturn shifted;\n\t}\n\n\t/**\n\t * Gets the farthest position which matches the callback using\n\t * {@link module:engine/view/treewalker~TreeWalker TreeWalker}.\n\t *\n\t * For example:\n\t *\n\t * \t\tgetLastMatchingPosition( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t * \t\tgetLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } ); // <p>foo[]</p> -> <p>{}foo</p>\n\t * \t\tgetLastMatchingPosition( value => false ); // Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t *\n\t * @returns {module:engine/view/position~Position} The position after the last item which matches the `skip` callback test.\n\t */\n\tgetLastMatchingPosition( skip, options = {} ) {\n\t\toptions.startPosition = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\t\ttreeWalker.skip( skip );\n\n\t\treturn treeWalker.position;\n\t}\n\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} Array with ancestors.\n\t */\n\tgetAncestors() {\n\t\tif ( this.parent.is( 'documentFragment' ) ) {\n\t\t\treturn [ this.parent ];\n\t\t} else {\n\t\t\treturn this.parent.getAncestors( { includeSelf: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both positions.\n\t *\n\t * @param {module:engine/view/position~Position} position\n\t * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor( position ) {\n\t\tconst ancestorsA = this.getAncestors();\n\t\tconst ancestorsB = position.getAncestors();\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Checks whether this position equals given position.\n\t *\n\t * @param {module:engine/view/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if positions are same.\n\t */\n\tisEqual( otherPosition ) {\n\t\treturn ( this.parent == otherPosition.parent && this.offset == otherPosition.offset );\n\t}\n\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~Position#isAfter\n\t * @see module:engine/view/position~Position#compareWith\n\t * @param {module:engine/view/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} Returns `true` if this position is before given position.\n\t */\n\tisBefore( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'before';\n\t}\n\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~Position#isBefore\n\t * @see module:engine/view/position~Position#compareWith\n\t * @param {module:engine/view/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} Returns `true` if this position is after given position.\n\t */\n\tisAfter( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'after';\n\t}\n\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 {module:engine/view/position~Position} otherPosition Position to compare with.\n\t * @returns {module:engine/view/position~PositionRelation}\n\t */\n\tcompareWith( otherPosition ) {\n\t\tif ( this.isEqual( otherPosition ) ) {\n\t\t\treturn 'same';\n\t\t}\n\n\t\t// If positions have same parent.\n\t\tif ( this.parent === otherPosition.parent ) {\n\t\t\treturn this.offset - otherPosition.offset < 0 ? 'before' : 'after';\n\t\t}\n\n\t\t// Get path from root to position's parent element.\n\t\tconst path = this.getAncestors();\n\t\tconst otherPath = otherPosition.getAncestors();\n\n\t\t// Compare both path arrays to find common ancestor.\n\t\tconst result = compareArrays( path, otherPath );\n\n\t\tlet commonAncestorIndex;\n\n\t\tswitch ( result ) {\n\t\t\tcase 0:\n\t\t\t\t// No common ancestors found.\n\t\t\t\treturn 'different';\n\n\t\t\tcase 'prefix':\n\t\t\t\tcommonAncestorIndex = path.length - 1;\n\t\t\t\tbreak;\n\n\t\t\tcase 'extension':\n\t\t\t\tcommonAncestorIndex = otherPath.length - 1;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tcommonAncestorIndex = result - 1;\n\t\t}\n\n\t\t// Common ancestor of two positions.\n\t\tconst commonAncestor = path[ commonAncestorIndex ];\n\t\tconst nextAncestor1 = path[ commonAncestorIndex + 1 ];\n\t\tconst nextAncestor2 = otherPath[ commonAncestorIndex + 1 ];\n\n\t\t// Check if common ancestor is not one of the parents.\n\t\tif ( commonAncestor === this.parent ) {\n\t\t\tconst index = this.offset - nextAncestor2.index;\n\n\t\t\treturn index <= 0 ? 'before' : 'after';\n\t\t} else if ( commonAncestor === otherPosition.parent ) {\n\t\t\tconst index = nextAncestor1.index - otherPosition.offset;\n\n\t\t\treturn index < 0 ? 'before' : 'after';\n\t\t}\n\n\t\tconst index = nextAncestor1.index - nextAncestor2.index;\n\n\t\t// Compare indexes of next ancestors inside common one.\n\t\treturn index < 0 ? 'before' : 'after';\n\t}\n\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~Position 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~Item 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~Position.createBefore},\n\t * * {@link module:engine/view/position~Position.createAfter},\n\t * * {@link module:engine/view/position~Position.createFromPosition}.\n\t *\n\t * @param {module:engine/view/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tstatic createAt( itemOrPosition, offset ) {\n\t\tif ( itemOrPosition instanceof Position ) {\n\t\t\treturn this.createFromPosition( itemOrPosition );\n\t\t} else {\n\t\t\tconst node = itemOrPosition;\n\n\t\t\tif ( offset == 'end' ) {\n\t\t\t\toffset = node.is( 'text' ) ? node.data.length : node.childCount;\n\t\t\t} else if ( offset == 'before' ) {\n\t\t\t\treturn this.createBefore( node );\n\t\t\t} else if ( offset == 'after' ) {\n\t\t\t\treturn this.createAfter( node );\n\t\t\t} else if ( !offset ) {\n\t\t\t\toffset = 0;\n\t\t\t}\n\n\t\t\treturn new Position( node, offset );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item after which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tstatic createAfter( item ) {\n\t\t// TextProxy is not a instance of Node so we need do handle it in specific way.\n\t\tif ( item.is( 'textProxy' ) ) {\n\t\t\treturn new Position( item.textNode, item.offsetInText + item.data.length );\n\t\t}\n\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position after a root.\n\t\t\t *\n\t\t\t * @error view-position-after-root\n\t\t\t * @param {module:engine/view/node~Node} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-position-after-root: You can not make position after root.', { root: item } );\n\t\t}\n\n\t\treturn new Position( item.parent, item.index + 1 );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item before which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tstatic createBefore( item ) {\n\t\t// TextProxy is not a instance of Node so we need do handle it in specific way.\n\t\tif ( item.is( 'textProxy' ) ) {\n\t\t\treturn new Position( item.textNode, item.offsetInText );\n\t\t}\n\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You cannot make a position before a root.\n\t\t\t *\n\t\t\t * @error view-position-before-root\n\t\t\t * @param {module:engine/view/node~Node} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-position-before-root: You can not make position before root.', { root: item } );\n\t\t}\n\n\t\treturn new Position( item.parent, item.index );\n\t}\n\n\t/**\n\t * Creates and returns a new instance of `Position`, which is equal to the passed position.\n\t *\n\t * @param {module:engine/view/position~Position} position Position to be cloned.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tstatic createFromPosition( position ) {\n\t\treturn new this( position.parent, position.offset );\n\t}\n}\n\n/**\n * A flag indicating whether this position is `'before'` or `'after'` or `'same'` as given position.\n * If positions are in different roots `'different'` flag is returned.\n *\n * @typedef {String} module:engine/view/position~PositionRelation\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/position.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/modelconsumable\n */\n\nimport TextProxy from '../model/textproxy';\n\n/**\n * Manages a list of consumable values for {@link module:engine/model/item~Item model items}.\n *\n * Consumables are various aspects of the model. A model item can be broken down into singular properties that might be\n * taken into consideration when converting that item.\n *\n * `ModelConsumable` is used by {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher} while analyzing changed\n * parts of {@link module:engine/model/document~Document the document}. The added / changed / removed model items are broken down\n * into singular properties (the item itself and it's attributes). All those parts are saved in `ModelConsumable`. Then,\n * during conversion, when given part of model item is converted (i.e. the view element has been inserted into the view,\n * but without attributes), consumable value is removed from `ModelConsumable`.\n *\n * For model items, `ModelConsumable` stores consumable values of one of following types: `insert`, `addAttribute:<attributeKey>`,\n * `changeAttribute:<attributeKey>`, `removeAttribute:<attributeKey>`.\n *\n * In most cases, it is enough to let {@link module:engine/conversion/modelconversiondispatcher~ModelConversionDispatcher}\n * gather consumable values, so there is no need to use\n * @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/model-selection-to-view-converters default model to view 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, other should not, because they would duplicate the results. Using `ModelConsumable` helps avoiding\n * this situation, because callbacks should only convert those values, which were not yet consumed from `ModelConsumable`.\n *\n * Consuming multiple values in a single callback:\n *\n *\t\t// Converter for custom `image` element that might have a `caption` element inside which changes\n *\t\t// how the image is displayed in the view:\n *\t\t//\n *\t\t// Model:\n *\t\t//\n *\t\t// [image]\n *\t\t// └─ [caption]\n *\t\t// └─ foo\n *\t\t//\n *\t\t// View:\n *\t\t//\n *\t\t// <figure>\n *\t\t// ├─ <img />\n *\t\t// └─ <caption>\n *\t\t// └─ foo\n *\t\tmodelConversionDispatcher.on( 'insert:image', ( evt, data, consumable, conversionApi ) => {\n *\t\t\t// First, consume the `image` element.\n *\t\t\tconsumable.consume( data.item, 'insert' );\n *\n *\t\t\t// Just create normal image element for the view.\n *\t\t\t// Maybe it will be \"decorated\" later.\n *\t\t\tconst viewImage = new ViewElement( 'img' );\n *\t\t\tconst insertPosition = conversionApi.mapper.toViewPosition( data.range.start );\n *\n *\t\t\t// Check if the `image` element has children.\n *\t\t\tif ( data.item.childCount > 0 ) {\n *\t\t\t\tconst modelCaption = data.item.getChild( 0 );\n *\n *\t\t\t\t// `modelCaption` insertion change is consumed from consumable values.\n *\t\t\t\t// It will not be converted by other converters, but it's children (probably some text) will be.\n *\t\t\t\t// Through mapping, converters for text will know where to insert contents of `modelCaption`.\n *\t\t\t\tif ( consumable.consume( modelCaption, 'insert' ) ) {\n *\t\t\t\t\tconst viewCaption = new ViewElement( 'figcaption' );\n *\n *\t\t\t\t\tconst viewImageHolder = new ViewElement( 'figure', null, [ viewImage, viewCaption ] );\n *\n *\t\t\t\t\tconversionApi.mapper.bindElements( modelCaption, viewCaption );\n *\t\t\t\t\tconversionApi.mapper.bindElements( data.item, viewImageHolder );\n *\t\t\t\t\tviewWriter.insert( insertPosition, viewImageHolder );\n *\t\t\t\t}\n *\t\t\t} else {\n *\t\t\t\tconversionApi.mapper.bindElements( data.item, viewImage );\n *\t\t\t\tviewWriter.insert( insertPosition, viewImage );\n *\t\t\t}\n *\n *\t\t\tevt.stop();\n *\t\t} );\n */\nexport default class ModelConsumable {\n\t/**\n\t * Creates an empty consumables list.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Contains list of consumable values.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/conversion/modelconsumable~ModelConsumable#_consumable\n\t\t */\n\t\tthis._consumable = new Map();\n\n\t\t/**\n\t\t * For each {@link module:engine/model/textproxy~TextProxy} added to `ModelConsumable`, this registry holds parent\n\t\t * of that `TextProxy` and start and end indices of that `TextProxy`. This allows identification of `TextProxy`\n\t\t * instances that points to the same part of the model but are different instances. Each distinct `TextProxy`\n\t\t * is given unique `Symbol` which is then registered as consumable. This process is transparent for `ModelConsumable`\n\t\t * API user because whenever `TextProxy` is added, tested, consumed or reverted, internal mechanisms of\n\t\t * `ModelConsumable` translates `TextProxy` to that unique `Symbol`.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/conversion/modelconsumable~ModelConsumable#_textProxyRegistry\n\t\t */\n\t\tthis._textProxyRegistry = new Map();\n\t}\n\n\t/**\n\t * Adds a consumable value to the consumables list and links it with given model item.\n\t *\n\t *\t\tmodelConsumable.add( modelElement, 'insert' ); // Add `modelElement` insertion change to consumable values.\n\t *\t\tmodelConsumable.add( modelElement, 'addAttribute:bold' ); // Add `bold` attribute insertion on `modelElement` change.\n\t *\t\tmodelConsumable.add( modelElement, 'removeAttribute:bold' ); // Add `bold` attribute removal on `modelElement` change.\n\t *\t\tmodelConsumable.add( modelSelection, 'selection' ); // Add `modelSelection` to consumable values.\n\t *\t\tmodelConsumable.add( modelSelection, 'selectionAttribute:bold' ); // Add `bold` attribute on `modelSelection` to consumables.\n\t *\t\tmodelConsumable.add( modelRange, 'range' ); // Add `modelRange` to consumable values.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection|module:engine/model/range~Range} item\n\t * Model item, range or selection that has the consumable.\n\t * @param {String} type Consumable type.\n\t */\n\tadd( item, type ) {\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item );\n\t\t}\n\n\t\tif ( !this._consumable.has( item ) ) {\n\t\t\tthis._consumable.set( item, new Map() );\n\t\t}\n\n\t\tthis._consumable.get( item ).set( type, true );\n\t}\n\n\t/**\n\t * Removes given consumable value from given model item.\n\t *\n\t *\t\tmodelConsumable.consume( modelElement, 'insert' ); // Remove `modelElement` insertion change from consumable values.\n\t *\t\tmodelConsumable.consume( modelElement, 'addAttribute:bold' ); // Remove `bold` attribute insertion on `modelElement` change.\n\t *\t\tmodelConsumable.consume( modelElement, 'removeAttribute:bold' ); // Remove `bold` attribute removal on `modelElement` change.\n\t *\t\tmodelConsumable.consume( modelSelection, 'selection' ); // Remove `modelSelection` from consumable values.\n\t *\t\tmodelConsumable.consume( modelSelection, 'selectionAttribute:bold' ); // Remove `bold` on `modelSelection` from consumables.\n\t *\t\tmodelConsumable.consume( modelRange, 'range' ); // Remove 'modelRange' from consumable values.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection|module:engine/model/range~Range} item\n\t * Model item, range or selection from which consumable will be consumed.\n\t * @param {String} type Consumable type.\n\t * @returns {Boolean} `true` if consumable value was available and was consumed, `false` otherwise.\n\t */\n\tconsume( item, type ) {\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item );\n\t\t}\n\n\t\tif ( this.test( item, type ) ) {\n\t\t\tthis._consumable.get( item ).set( type, false );\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Tests whether there is a consumable value of given type connected with given model item.\n\t *\n\t *\t\tmodelConsumable.test( modelElement, 'insert' ); // Check for `modelElement` insertion change.\n\t *\t\tmodelConsumable.test( modelElement, 'addAttribute:bold' ); // Check for `bold` attribute insertion on `modelElement` change.\n\t *\t\tmodelConsumable.test( modelElement, 'removeAttribute:bold' ); // Check for `bold` attribute removal on `modelElement` change.\n\t *\t\tmodelConsumable.test( modelSelection, 'selection' ); // Check if `modelSelection` is consumable.\n\t *\t\tmodelConsumable.test( modelSelection, 'selectionAttribute:bold' ); // Check if `bold` on `modelSelection` is consumable.\n\t *\t\tmodelConsumable.test( modelRange, 'range' ); // Check if `modelRange` is consumable.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection|module:engine/model/range~Range} item\n\t * Model item, range or selection to be tested.\n\t * @param {String} type Consumable type.\n\t * @returns {null|Boolean} `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\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item );\n\t\t}\n\n\t\tconst itemConsumables = this._consumable.get( item );\n\n\t\tif ( itemConsumables === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst value = itemConsumables.get( type );\n\n\t\tif ( value === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Reverts consuming of consumable value.\n\t *\n\t *\t\tmodelConsumable.revert( modelElement, 'insert' ); // Revert consuming `modelElement` insertion change.\n\t *\t\tmodelConsumable.revert( modelElement, 'addAttribute:bold' ); // Revert consuming `bold` attribute insert from `modelElement`.\n\t *\t\tmodelConsumable.revert( modelElement, 'removeAttribute:bold' ); // Revert consuming `bold` attribute remove from `modelElement`.\n\t *\t\tmodelConsumable.revert( modelSelection, 'selection' ); // Revert consuming `modelSelection`.\n\t *\t\tmodelConsumable.revert( modelSelection, 'selectionAttribute:bold' ); // Revert consuming `bold` from `modelSelection`.\n\t *\t\tmodelConsumable.revert( modelRange, 'range' ); // Revert consuming `modelRange`.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection|module:engine/model/range~Range} item\n\t * Model item, range or selection to be reverted.\n\t * @param {String} type Consumable type.\n\t * @returns {null|Boolean} `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\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item );\n\t\t}\n\n\t\tconst test = this.test( item, type );\n\n\t\tif ( test === false ) {\n\t\t\tthis._consumable.get( item ).set( type, true );\n\n\t\t\treturn true;\n\t\t} else if ( test === true ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets a unique symbol for passed {@link module:engine/model/textproxy~TextProxy} instance. All `TextProxy` instances that\n\t * have same parent, same start index and same end index will get the same symbol.\n\t *\n\t * Used internally to correctly consume `TextProxy` instances.\n\t *\n\t * @private\n\t * @param {module:engine/model/textproxy~TextProxy} textProxy `TextProxy` instance to get a symbol for.\n\t * @returns {Symbol} Symbol representing all equal instances of `TextProxy`.\n\t */\n\t_getSymbolForTextProxy( textProxy ) {\n\t\tlet symbol = null;\n\n\t\tconst startMap = this._textProxyRegistry.get( textProxy.startOffset );\n\n\t\tif ( startMap ) {\n\t\t\tconst endMap = startMap.get( textProxy.endOffset );\n\n\t\t\tif ( endMap ) {\n\t\t\t\tsymbol = endMap.get( textProxy.parent );\n\t\t\t}\n\t\t}\n\n\t\tif ( !symbol ) {\n\t\t\tsymbol = this._addSymbolForTextProxy( textProxy.startOffset, textProxy.endOffset, textProxy.parent );\n\t\t}\n\n\t\treturn symbol;\n\t}\n\n\t/**\n\t * Adds a symbol for given properties that characterizes a {@link module:engine/model/textproxy~TextProxy} instance.\n\t *\n\t * Used internally to correctly consume `TextProxy` instances.\n\t *\n\t * @private\n\t * @param {Number} startIndex Text proxy start index in it's parent.\n\t * @param {Number} endIndex Text proxy end index in it's parent.\n\t * @param {module:engine/model/element~Element} parent Text proxy parent.\n\t * @returns {Symbol} Symbol generated for given properties.\n\t */\n\t_addSymbolForTextProxy( start, end, parent ) {\n\t\tconst symbol = Symbol( 'textProxySymbol' );\n\t\tlet startMap, endMap;\n\n\t\tstartMap = this._textProxyRegistry.get( start );\n\n\t\tif ( !startMap ) {\n\t\t\tstartMap = new Map();\n\t\t\tthis._textProxyRegistry.set( start, startMap );\n\t\t}\n\n\t\tendMap = startMap.get( end );\n\n\t\tif ( !endMap ) {\n\t\t\tendMap = new Map();\n\t\t\tstartMap.set( end, endMap );\n\t\t}\n\n\t\tendMap.set( parent, symbol );\n\n\t\treturn symbol;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/modelconsumable.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/viewconsumable\n */\n\nimport isArray from '@ckeditor/ckeditor5-utils/src/lib/lodash/isArray';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Class used for handling consumption of view {@link module:engine/view/element~Element elements},\n * {@link module:engine/view/text~Text text nodes} and {@link module:engine/view/documentfragment~DocumentFragment 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 *\t\tviewConsumable.add( element, { name: true } ); // Adds element's name as ready to be consumed.\n *\t\tviewConsumable.add( textNode ); // Adds text node for consumption.\n *\t\tviewConsumable.add( docFragment ); // Adds document fragment for consumption.\n *\t\tviewConsumable.test( element, { name: true } ); // Tests if element's name can be consumed.\n *\t\tviewConsumable.test( textNode ); // Tests if text node can be consumed.\n *\t\tviewConsumable.test( docFragment ); // Tests if document fragment can be consumed.\n *\t\tviewConsumable.consume( element, { name: true } ); // Consume element's name.\n *\t\tviewConsumable.consume( textNode ); // Consume text node.\n *\t\tviewConsumable.consume( docFragment ); // Consume document fragment.\n *\t\tviewConsumable.revert( element, { name: true } ); // Revert already consumed element's name.\n *\t\tviewConsumable.revert( textNode ); // Revert already consumed text node.\n *\t\tviewConsumable.revert( docFragment ); // Revert already consumed document fragment.\n */\nexport default class ViewConsumable {\n\t/**\n\t * Creates new ViewConsumable.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Map of consumable elements. If {@link module:engine/view/element~Element element} is used as a key,\n\t\t * {@link module:engine/conversion/viewconsumable~ViewElementConsumables ViewElementConsumables} instance is stored as value.\n\t\t * For {@link module:engine/view/text~Text text nodes} and\n\t\t * {@link module:engine/view/documentfragment~DocumentFragment document fragments} boolean value is stored as value.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map.<module:engine/conversion/viewconsumable~ViewElementConsumables|Boolean>}\n\t\t*/\n\t\tthis._consumables = new Map();\n\t}\n\n\t/**\n\t * Adds {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} as ready to be consumed.\n\t *\n\t *\t\tviewConsumable.add( p, { name: true } ); // Adds element's name to consume.\n\t *\t\tviewConsumable.add( p, { attribute: 'name' } ); // Adds element's attribute.\n\t *\t\tviewConsumable.add( p, { class: 'foobar' } ); // Adds element's class.\n\t *\t\tviewConsumable.add( p, { style: 'color' } ); // Adds element's style\n\t *\t\tviewConsumable.add( p, { attribute: 'name', style: 'color' } ); // Adds attribute and style.\n\t *\t\tviewConsumable.add( p, { class: [ 'baz', 'bar' ] } ); // Multiple consumables can be provided.\n\t *\t\tviewConsumable.add( textNode ); // Adds text node to consume.\n\t *\t\tviewConsumable.add( docFragment ); // Adds document fragment to consume.\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 *\t\tviewConsumable.add( p, { attribute: 'style' } ); // This call will throw an exception.\n\t *\t\tviewConsumable.add( p, { style: 'color' } ); // This is properly handled style.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/text~Text|module:engine/view/documentfragment~DocumentFragment} element\n\t * @param {Object} [consumables] Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param {Boolean} consumables.name If set to true element's name will be included.\n\t * @param {String|Array.<String>} consumables.attribute Attribute name or array of attribute names.\n\t * @param {String|Array.<String>} consumables.class Class name or array of class names.\n\t * @param {String|Array.<String>} consumables.style Style name or array of style names.\n\t */\n\tadd( element, consumables ) {\n\t\tlet elementConsumables;\n\n\t\t// For text nodes and document fragments just mark them as consumable.\n\t\tif ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {\n\t\t\tthis._consumables.set( element, true );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// For elements create new ViewElementConsumables or update already existing one.\n\t\tif ( !this._consumables.has( element ) ) {\n\t\t\telementConsumables = new ViewElementConsumables();\n\t\t\tthis._consumables.set( element, elementConsumables );\n\t\t} else {\n\t\t\telementConsumables = this._consumables.get( element );\n\t\t}\n\n\t\telementConsumables.add( consumables );\n\t}\n\n\t/**\n\t * Tests if {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment 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 *\t\tviewConsumable.test( p, { name: true } ); // Tests element's name.\n\t *\t\tviewConsumable.test( p, { attribute: 'name' } ); // Tests attribute.\n\t *\t\tviewConsumable.test( p, { class: 'foobar' } ); // Tests class.\n\t *\t\tviewConsumable.test( p, { style: 'color' } ); // Tests style.\n\t *\t\tviewConsumable.test( p, { attribute: 'name', style: 'color' } ); // Tests attribute and style.\n\t *\t\tviewConsumable.test( p, { class: [ 'baz', 'bar' ] } ); // Multiple consumables can be tested.\n\t *\t\tviewConsumable.test( textNode ); // Tests text node.\n\t *\t\tviewConsumable.test( docFragment ); // Tests document fragment.\n\t *\n\t * Testing classes and styles as attribute will test if all added classes/styles can be consumed.\n\t *\n\t *\t\tviewConsumable.test( p, { attribute: 'class' } ); // Tests if all added classes can be consumed.\n\t *\t\tviewConsumable.test( p, { attribute: 'style' } ); // Tests if all added styles can be consumed.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/text~Text|module:engine/view/documentfragment~DocumentFragment} element\n\t * @param {Object} [consumables] Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param {Boolean} consumables.name If set to true element's name will be included.\n\t * @param {String|Array.<String>} consumables.attribute Attribute name or array of attribute names.\n\t * @param {String|Array.<String>} consumables.class Class name or array of class names.\n\t * @param {String|Array.<String>} consumables.style Style name or array of style names.\n\t * @returns {Boolean|null} 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\n\t\tif ( elementConsumables === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// For text nodes and document fragments return stored boolean value.\n\t\tif ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {\n\t\t\treturn elementConsumables;\n\t\t}\n\n\t\t// For elements test consumables object.\n\t\treturn elementConsumables.test( consumables );\n\t}\n\n\t/**\n\t * Consumes {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment 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 *\t\tviewConsumable.consume( p, { name: true } ); // Consumes element's name.\n\t *\t\tviewConsumable.consume( p, { attribute: 'name' } ); // Consumes element's attribute.\n\t *\t\tviewConsumable.consume( p, { class: 'foobar' } ); // Consumes element's class.\n\t *\t\tviewConsumable.consume( p, { style: 'color' } ); // Consumes element's style.\n\t *\t\tviewConsumable.consume( p, { attribute: 'name', style: 'color' } ); // Consumes attribute and style.\n\t *\t\tviewConsumable.consume( p, { class: [ 'baz', 'bar' ] } ); // Multiple consumables can be consumed.\n\t *\t\tviewConsumable.consume( textNode ); // Consumes text node.\n\t *\t\tviewConsumable.consume( docFragment ); // Consumes document fragment.\n\t *\n\t * Consuming classes and styles as attribute will test if all added classes/styles can be consumed.\n\t *\n\t *\t\tviewConsumable.consume( p, { attribute: 'class' } ); // Consume only if all added classes can be consumed.\n\t *\t\tviewConsumable.consume( p, { attribute: 'style' } ); // Consume only if all added styles can be consumed.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/text~Text|module:engine/view/documentfragment~DocumentFragment} element\n\t * @param {Object} [consumables] Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param {Boolean} consumables.name If set to true element's name will be included.\n\t * @param {String|Array.<String>} consumables.attribute Attribute name or array of attribute names.\n\t * @param {String|Array.<String>} consumables.class Class name or array of class names.\n\t * @param {String|Array.<String>} consumables.style Style name or array of style names.\n\t * @returns {Boolean} 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 ( this.test( element, consumables ) ) {\n\t\t\tif ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {\n\t\t\t\t// For text nodes and document fragments set value to false.\n\t\t\t\tthis._consumables.set( element, false );\n\t\t\t} else {\n\t\t\t\t// For elements - consume consumables object.\n\t\t\t\tthis._consumables.get( element ).consume( consumables );\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Reverts {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment 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 *\t\tviewConsumable.revert( p, { name: true } ); // Reverts element's name.\n\t *\t\tviewConsumable.revert( p, { attribute: 'name' } ); // Reverts element's attribute.\n\t *\t\tviewConsumable.revert( p, { class: 'foobar' } ); // Reverts element's class.\n\t *\t\tviewConsumable.revert( p, { style: 'color' } ); // Reverts element's style.\n\t *\t\tviewConsumable.revert( p, { attribute: 'name', style: 'color' } ); // Reverts attribute and style.\n\t *\t\tviewConsumable.revert( p, { class: [ 'baz', 'bar' ] } ); // Multiple names can be reverted.\n\t *\t\tviewConsumable.revert( textNode ); // Reverts text node.\n\t *\t\tviewConsumable.revert( docFragment ); // Reverts document fragment.\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 *\t\tviewConsumable.revert( p, { attribute: 'class' } ); // Reverts all classes added for consumption.\n\t *\t\tviewConsumable.revert( p, { attribute: 'style' } ); // Reverts all styles added for consumption.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/text~Text|module:engine/view/documentfragment~DocumentFragment} element\n\t * @param {Object} [consumables] Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param {Boolean} consumables.name If set to true element's name will be included.\n\t * @param {String|Array.<String>} consumables.attribute Attribute name or array of attribute names.\n\t * @param {String|Array.<String>} consumables.class Class name or array of class names.\n\t * @param {String|Array.<String>} consumables.style Style name or array of style names.\n\t */\n\trevert( element, consumables ) {\n\t\tconst elementConsumables = this._consumables.get( element );\n\n\t\tif ( elementConsumables !== undefined ) {\n\t\t\tif ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {\n\t\t\t\t// For text nodes and document fragments - set consumable to true.\n\t\t\t\tthis._consumables.set( element, true );\n\t\t\t} else {\n\t\t\t\t// For elements - revert items from consumables object.\n\t\t\t\telementConsumables.revert( consumables );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates consumable object from {@link module:engine/view/element~Element view element}. Consumable object will include\n\t * element's name and all its attributes, classes and styles.\n\t *\n\t * @static\n\t * @param {module:engine/view/element~Element} element\n\t * @returns {Object} consumables\n\t */\n\tstatic consumablesFromElement( element ) {\n\t\tconst consumables = {\n\t\t\tname: true,\n\t\t\tattribute: [],\n\t\t\tclass: [],\n\t\t\tstyle: []\n\t\t};\n\n\t\tconst attributes = element.getAttributeKeys();\n\n\t\tfor ( const attribute of attributes ) {\n\t\t\t// Skip classes and styles - will be added separately.\n\t\t\tif ( attribute == 'style' || attribute == 'class' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconsumables.attribute.push( attribute );\n\t\t}\n\n\t\tconst classes = element.getClassNames();\n\n\t\tfor ( const className of classes ) {\n\t\t\tconsumables.class.push( className );\n\t\t}\n\n\t\tconst styles = element.getStyleNames();\n\n\t\tfor ( const style of styles ) {\n\t\t\tconsumables.style.push( style );\n\t\t}\n\n\t\treturn consumables;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/viewconsumable~ViewConsumable ViewConsumable} instance from\n\t * {@link module:engine/view/node~Node node} or {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t * Instance will contain all elements, child nodes, attributes, styles and classes added for consumption.\n\t *\n\t * @static\n\t * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} from View node or document fragment\n\t * from which `ViewConsumable` will be created.\n\t * @param {module:engine/conversion/viewconsumable~ViewConsumable} [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 ) {\n\t\t\tinstance = new ViewConsumable();\n\t\t}\n\n\t\tif ( from.is( 'text' ) ) {\n\t\t\tinstance.add( from );\n\n\t\t\treturn instance;\n\t\t}\n\n\t\t// Add `from` itself, if it is an element.\n\t\tif ( from.is( 'element' ) ) {\n\t\t\tinstance.add( from, ViewConsumable.consumablesFromElement( from ) );\n\t\t}\n\n\t\tif ( from.is( 'documentFragment' ) ) {\n\t\t\tinstance.add( from );\n\t\t}\n\n\t\tfor ( const child of from.getChildren() ) {\n\t\t\tinstance = ViewConsumable.createFrom( child, instance );\n\t\t}\n\n\t\treturn instance;\n\t}\n}\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~Element}.\n *\n * @private\n */\nclass ViewElementConsumables {\n\t/**\n\t * Creates ViewElementConsumables instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Flag indicating if name of the element can be consumed.\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._canConsumeName = null;\n\n\t\t/**\n\t\t * Contains maps of element's consumables: attributes, classes and styles.\n\t\t *\n\t\t * @private\n\t\t * @member {Object}\n\t\t */\n\t\tthis._consumables = {\n\t\t\tattribute: new Map(),\n\t\t\tstyle: new Map(),\n\t\t\tclass: new Map()\n\t\t};\n\t}\n\n\t/**\n\t * Adds consumable parts of the {@link module:engine/view/element~Element 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 *\t\tconsumables.add( { name: true } );\n\t *\n\t * Attributes classes and styles:\n\t *\n\t *\t\tconsumables.add( { attribute: 'title', class: 'foo', style: 'color' } );\n\t *\t\tconsumables.add( { attribute: [ 'title', 'name' ], class: [ 'foo', 'bar' ] );\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 {Object} consumables Object describing which parts of the element can be consumed.\n\t * @param {Boolean} consumables.name If set to `true` element's name will be added as consumable.\n\t * @param {String|Array.<String>} consumables.attribute Attribute name or array of attribute names to add as consumable.\n\t * @param {String|Array.<String>} consumables.class Class name or array of class names to add as consumable.\n\t * @param {String|Array.<String>} consumables.style Style name or array of style names to add as consumable.\n\t */\n\tadd( consumables ) {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = true;\n\t\t}\n\n\t\tfor ( const type in this._consumables ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._add( type, consumables[ type ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Tests if parts of the {@link module:engine/view/node~Node view node} can be consumed.\n\t *\n\t * Element's name can be tested:\n\t *\n\t *\t\tconsumables.test( { name: true } );\n\t *\n\t * Attributes classes and styles:\n\t *\n\t *\t\tconsumables.test( { attribute: 'title', class: 'foo', style: 'color' } );\n\t *\t\tconsumables.test( { attribute: [ 'title', 'name' ], class: [ 'foo', 'bar' ] );\n\t *\n\t * @param {Object} consumables Object describing which parts of the element should be tested.\n\t * @param {Boolean} consumables.name If set to `true` element's name will be tested.\n\t * @param {String|Array.<String>} consumables.attribute Attribute name or array of attribute names to test.\n\t * @param {String|Array.<String>} consumables.class Class name or array of class names to test.\n\t * @param {String|Array.<String>} consumables.style Style name or array of style names to test.\n\t * @returns {Boolean|null} `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\t// Check if name can be consumed.\n\t\tif ( consumables.name && !this._canConsumeName ) {\n\t\t\treturn this._canConsumeName;\n\t\t}\n\n\t\tfor ( const type in this._consumables ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tconst value = this._test( type, consumables[ type ] );\n\n\t\t\t\tif ( value !== true ) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return true only if all can be consumed.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Consumes parts of {@link module:engine/view/element~Element view element}. This function does not check if consumable item\n\t * is already consumed - it consumes all consumable items provided.\n\t * Element's name can be consumed:\n\t *\n\t *\t\tconsumables.consume( { name: true } );\n\t *\n\t * Attributes classes and styles:\n\t *\n\t *\t\tconsumables.consume( { attribute: 'title', class: 'foo', style: 'color' } );\n\t *\t\tconsumables.consume( { attribute: [ 'title', 'name' ], class: [ 'foo', 'bar' ] );\n\t *\n\t * @param {Object} consumables Object describing which parts of the element should be consumed.\n\t * @param {Boolean} consumables.name If set to `true` element's name will be consumed.\n\t * @param {String|Array.<String>} consumables.attribute Attribute name or array of attribute names to consume.\n\t * @param {String|Array.<String>} consumables.class Class name or array of class names to consume.\n\t * @param {String|Array.<String>} consumables.style Style name or array of style names to consume.\n\t */\n\tconsume( consumables ) {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = false;\n\t\t}\n\n\t\tfor ( const type in this._consumables ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._consume( type, consumables[ type ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Revert already consumed parts of {@link module:engine/view/element~Element view Element}, so they can be consumed once again.\n\t * Element's name can be reverted:\n\t *\n\t *\t\tconsumables.revert( { name: true } );\n\t *\n\t * Attributes classes and styles:\n\t *\n\t *\t\tconsumables.revert( { attribute: 'title', class: 'foo', style: 'color' } );\n\t *\t\tconsumables.revert( { attribute: [ 'title', 'name' ], class: [ 'foo', 'bar' ] );\n\t *\n\t * @param {Object} consumables Object describing which parts of the element should be reverted.\n\t * @param {Boolean} consumables.name If set to `true` element's name will be reverted.\n\t * @param {String|Array.<String>} consumables.attribute Attribute name or array of attribute names to revert.\n\t * @param {String|Array.<String>} consumables.class Class name or array of class names to revert.\n\t * @param {String|Array.<String>} consumables.style Style name or array of style names to revert.\n\t */\n\trevert( consumables ) {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = true;\n\t\t}\n\n\t\tfor ( const type in this._consumables ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._revert( type, consumables[ type ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that adds consumables of a given type: attribute, class or style.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * type is provided - it should be handled separately by providing actual style/class type.\n\t *\n\t * @private\n\t * @param {String} type Type of the consumable item: `attribute`, `class` or `style`.\n\t * @param {String|Array.<String>} item Consumable item or array of items.\n\t */\n\t_add( type, item ) {\n\t\tconst items = isArray( item ) ? item : [ item ];\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attribute' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\t/**\n\t\t\t\t * Class and style attributes should be handled separately in\n\t\t\t\t * {@link module:engine/conversion/viewconsumable~ViewConsumable#add `ViewConsumable#add()`}.\n\t\t\t\t *\n\t\t\t\t * What you have done is trying to use:\n\t\t\t\t *\n\t\t\t\t *\t\tconsumables.add( { attribute: [ 'class', 'style' ] } );\n\t\t\t\t *\n\t\t\t\t * While each class and style should be registered separately:\n\t\t\t\t *\n\t\t\t\t *\t\tconsumables.add( { class: 'some-class', style: 'font-weight' } );\n\t\t\t\t *\n\t\t\t\t * @error viewconsumable-invalid-attribute\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'viewconsumable-invalid-attribute: Classes and styles should be handled separately.' );\n\t\t\t}\n\n\t\t\tconsumables.set( name, true );\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that tests consumables of a given type: attribute, class or style.\n\t *\n\t * @private\n\t * @param {String} type Type of the consumable item: `attribute`, `class` or `style`.\n\t * @param {String|Array.<String>} item Consumable item or array of items.\n\t * @returns {Boolean|null} Returns `true` if all items can be consumed, `null` when one of the items cannot be\n\t * consumed and `false` when one of the items is already consumed.\n\t */\n\t_test( type, item ) {\n\t\tconst items = isArray( item ) ? item : [ item ];\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attribute' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\t// Check all classes/styles if class/style attribute is tested.\n\t\t\t\tconst value = this._test( name, [ ...this._consumables[ name ].keys() ] );\n\n\t\t\t\tif ( value !== true ) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst value = consumables.get( name );\n\t\t\t\t// Return null if attribute is not found.\n\t\t\t\tif ( value === undefined ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif ( !value ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Helper method that consumes items of a given type: attribute, class or style.\n\t *\n\t * @private\n\t * @param {String} type Type of the consumable item: `attribute`, `class` or `style`.\n\t * @param {String|Array.<String>} item Consumable item or array of items.\n\t */\n\t_consume( type, item ) {\n\t\tconst items = isArray( item ) ? item : [ item ];\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attribute' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\t// If class or style is provided for consumption - consume them all.\n\t\t\t\tthis._consume( name, [ ...this._consumables[ name ].keys() ] );\n\t\t\t} else {\n\t\t\t\tconsumables.set( name, false );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that reverts items of a given type: attribute, class or style.\n\t *\n\t * @private\n\t * @param {String} type Type of the consumable item: `attribute`, `class` or , `style`.\n\t * @param {String|Array.<String>} item Consumable item or array of items.\n\t */\n\t_revert( type, item ) {\n\t\tconst items = isArray( item ) ? item : [ item ];\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attribute' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\t// If class or style is provided for reverting - revert them all.\n\t\t\t\tthis._revert( name, [ ...this._consumables[ name ].keys() ] );\n\t\t\t} else {\n\t\t\t\tconst value = consumables.get( name );\n\n\t\t\t\tif ( value === false ) {\n\t\t\t\t\tconsumables.set( name, true );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/conversion/viewconsumable.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/operation\n */\n\nimport clone from '@ckeditor/ckeditor5-utils/src/lib/lodash/clone';\n\n/**\n * Abstract base operation class.\n *\n * @abstract\n */\nexport default class Operation {\n\t/**\n\t * Base operation constructor.\n\t * @param {Number} baseVersion {@link module:engine/model/document~Document#version} on which the operation can be applied.\n\t */\n\tconstructor( baseVersion ) {\n\t\t/**\n\t\t * {@link module:engine/model/document~Document#version} on which operation can be applied. If you try to\n\t\t * {@link module:engine/model/document~Document#applyOperation apply} operation with different base version than the\n\t\t * {@link module:engine/model/document~Document#version document version} the\n\t\t * {@link module:utils/ckeditorerror~CKEditorError model-document-applyOperation-wrong-version} error is thrown.\n\t\t *\n\t\t * @member {Number}\n\t\t */\n\t\tthis.baseVersion = baseVersion;\n\n\t\t/**\n\t\t * Operation type.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} #type\n\t\t */\n\n\t\t/**\n\t\t * {@link module:engine/model/delta/delta~Delta Delta} which the operation is a part of. This property is set by the\n\t\t * {@link module:engine/model/delta/delta~Delta delta} when the operations is added to it by the\n\t\t * {@link module:engine/model/delta/delta~Delta#addOperation} method.\n\t\t *\n\t\t * @member {module:engine/model/delta/delta~Delta} #delta\n\t\t */\n\n\t\t/**\n\t\t * Creates and returns an operation that has the same parameters as this operation.\n\t\t *\n\t\t * @method #clone\n\t\t * @returns {module:engine/model/operation/operation~Operation} Clone of this operation.\n\t\t */\n\n\t\t/**\n\t\t * Creates and returns a reverse operation. Reverse operation when executed right after\n\t\t * the original operation will bring back tree model state to the point before the original\n\t\t * operation execution. In other words, it reverses changes done by the original operation.\n\t\t *\n\t\t * Keep in mind that tree model state may change since executing the original operation,\n\t\t * so reverse operation will be \"outdated\". In that case you will need to\n\t\t * {@link module:engine/model/operation/transform~transform} it by all operations that were executed after the original operation.\n\t\t *\n\t\t * @method #getReversed\n\t\t * @returns {module:engine/model/operation/operation~Operation} Reversed operation.\n\t\t */\n\n\t\t/**\n\t\t * Executes the operation - modifications described by the operation attributes\n\t\t * will be applied to the tree model.\n\t\t *\n\t\t * @protected\n\t\t * @method #_execute\n\t\t * @returns {Object} Object with additional information about the applied changes. It properties depends on the\n\t\t * operation type.\n\t\t */\n\t}\n\n\t/**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @method #toJSON\n\t * @returns {Object} Clone of this object with the delta property replaced with string.\n\t */\n\ttoJSON() {\n\t\tconst json = clone( this, true );\n\n\t\tjson.__className = this.constructor.className;\n\n\t\t// Remove parent delta to avoid circular dependencies.\n\t\tdelete json.delta;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Name of the operation class used for serialization.\n\t *\n\t * @type {String}\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.Operation';\n\t}\n\n\t/**\n\t * Creates Operation object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} doc Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/operation~Operation}\n\t */\n\tstatic fromJSON( json ) {\n\t\treturn new this( json.baseVersion );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/operation.js\n// module id = null\n// module chunks = ","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_setCacheAdd.js\n// module id = null\n// module chunks = ","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_setCacheHas.js\n// module id = null\n// module chunks = ","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_arraySome.js\n// module id = null\n// module chunks = ","import SetCache from './_SetCache';\nimport arraySome from './_arraySome';\n\n/** Used to compose bitmasks for comparison styles. */\nvar UNORDERED_COMPARE_FLAG = 1,\n PARTIAL_COMPARE_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Function} customizer The function to customize comparisons.\n * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n * for more details.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, equalFunc, customizer, bitmask, stack) {\n var isPartial = bitmask & PARTIAL_COMPARE_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!seen.has(othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {\n return seen.add(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, customizer, bitmask, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n return result;\n}\n\nexport default equalArrays;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_equalArrays.js\n// module id = null\n// module chunks = ","import Symbol from './_Symbol';\nimport Uint8Array from './_Uint8Array';\nimport equalArrays from './_equalArrays';\nimport mapToArray from './_mapToArray';\nimport setToArray from './_setToArray';\n\n/** Used to compose bitmasks for comparison styles. */\nvar UNORDERED_COMPARE_FLAG = 1,\n PARTIAL_COMPARE_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Function} customizer The function to customize comparisons.\n * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n * for more details.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n // Coerce dates and booleans to numbers, dates to milliseconds and\n // booleans to `1` or `0` treating invalid dates coerced to `NaN` as\n // not equal.\n return +object == +other;\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case numberTag:\n // Treat `NaN` vs. `NaN` as equal.\n return (object != +object) ? other != +other : object == +other;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & PARTIAL_COMPARE_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= UNORDERED_COMPARE_FLAG;\n stack.set(object, other);\n\n // Recursively compare objects (susceptible to call stack limits).\n return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nexport default equalByTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_equalByTag.js\n// module id = null\n// module chunks = ","import baseHas from './_baseHas';\nimport keys from './keys';\n\n/** Used to compose bitmasks for comparison styles. */\nvar PARTIAL_COMPARE_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Function} customizer The function to customize comparisons.\n * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n * for more details.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, equalFunc, customizer, bitmask, stack) {\n var isPartial = bitmask & PARTIAL_COMPARE_FLAG,\n objProps = keys(object),\n objLength = objProps.length,\n othProps = keys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : baseHas(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n return result;\n}\n\nexport default equalObjects;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_equalObjects.js\n// module id = null\n// module chunks = ","import isLength from './isLength';\nimport isObjectLike from './isObjectLike';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nfunction isTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[objectToString.call(value)];\n}\n\nexport default isTypedArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isTypedArray.js\n// module id = null\n// module chunks = ","import Stack from './_Stack';\nimport equalArrays from './_equalArrays';\nimport equalByTag from './_equalByTag';\nimport equalObjects from './_equalObjects';\nimport getTag from './_getTag';\nimport isArray from './isArray';\nimport isHostObject from './_isHostObject';\nimport isTypedArray from './isTypedArray';\n\n/** Used to compose bitmasks for comparison styles. */\nvar PARTIAL_COMPARE_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`\n * for more details.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = arrayTag,\n othTag = arrayTag;\n\n if (!objIsArr) {\n objTag = getTag(object);\n objTag = objTag == argsTag ? objectTag : objTag;\n }\n if (!othIsArr) {\n othTag = getTag(other);\n othTag = othTag == argsTag ? objectTag : othTag;\n }\n var objIsObj = objTag == objectTag && !isHostObject(object),\n othIsObj = othTag == objectTag && !isHostObject(other),\n isSameTag = objTag == othTag;\n\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)\n : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);\n }\n if (!(bitmask & PARTIAL_COMPARE_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, equalFunc, customizer, bitmask, stack);\n}\n\nexport default baseIsEqualDeep;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseIsEqualDeep.js\n// module id = null\n// module chunks = ","import baseIsEqual from './_baseIsEqual';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are **not** supported.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent,\n * else `false`.\n * @example\n *\n * var object = { 'user': 'fred' };\n * var other = { 'user': 'fred' };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n return baseIsEqual(value, other);\n}\n\nexport default isEqual;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isEqual.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/attributeoperation\n */\n\nimport Operation from './operation';\nimport Range from '../range';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport writer from '../writer';\nimport isEqual from '@ckeditor/ckeditor5-utils/src/lib/lodash/isEqual';\n\n/**\n * Operation to change nodes' attribute.\n *\n * Using this class you can add, remove or change value of the attribute.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class AttributeOperation extends Operation {\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 {module:engine/model/range~Range} range Range on which the operation should be applied.\n\t * @param {String} 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 {Number} baseVersion {@link module:engine/model/document~Document#version} on which the operation can be applied.\n\t */\n\tconstructor( range, key, oldValue, newValue, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Range on which operation should be applied.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/range~Range}\n\t\t */\n\t\tthis.range = Range.createFromRange( range );\n\n\t\t/**\n\t\t * Key of an attribute to change or remove.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.key = key;\n\n\t\t/**\n\t\t * Old value of the attribute with given key or `null`, if attribute was not set before.\n\t\t *\n\t\t * @readonly\n\t\t * @member {*}\n\t\t */\n\t\tthis.oldValue = oldValue === undefined ? null : oldValue;\n\n\t\t/**\n\t\t * New value of the attribute with given key or `null`, if operation should remove attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @member {*}\n\t\t */\n\t\tthis.newValue = newValue === undefined ? null : newValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\tif ( this.oldValue === null ) {\n\t\t\treturn 'addAttribute';\n\t\t} else if ( this.newValue === null ) {\n\t\t\treturn 'removeAttribute';\n\t\t} else {\n\t\t\treturn 'changeAttribute';\n\t\t}\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/attributeoperation~AttributeOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new AttributeOperation( this.range, this.key, this.oldValue, this.newValue, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}\n\t */\n\tgetReversed() {\n\t\treturn new AttributeOperation( this.range, this.key, this.newValue, this.oldValue, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\t// Validation.\n\t\tfor ( const item of this.range.getItems() ) {\n\t\t\tif ( this.oldValue !== null && !isEqual( item.getAttribute( this.key ), this.oldValue ) ) {\n\t\t\t\t/**\n\t\t\t\t * Changed node has different attribute value than operation's old attribute value.\n\t\t\t\t *\n\t\t\t\t * @error operation-attribute-wrong-old-value\n\t\t\t\t * @param {module:engine/model/item~Item} item\n\t\t\t\t * @param {String} key\n\t\t\t\t * @param {*} value\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'attribute-operation-wrong-old-value: Changed node has different attribute value than operation\\'s ' +\n\t\t\t\t\t'old attribute value.',\n\t\t\t\t\t{ item, key: this.key, value: this.oldValue }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( this.oldValue === null && this.newValue !== null && item.hasAttribute( this.key ) ) {\n\t\t\t\t/**\n\t\t\t\t * The attribute with given key already exists for the given node.\n\t\t\t\t *\n\t\t\t\t * @error attribute-operation-attribute-exists\n\t\t\t\t * @param {module:engine/model/node~Node} node\n\t\t\t\t * @param {String} key\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'attribute-operation-attribute-exists: The attribute with given key already exists.',\n\t\t\t\t\t{ node: item, key: this.key }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// If value to set is same as old value, don't do anything.\n\t\tif ( !isEqual( this.oldValue, this.newValue ) ) {\n\t\t\t// Execution.\n\t\t\twriter.setAttribute( this.range, this.key, this.newValue );\n\t\t}\n\n\t\treturn { range: this.range, key: this.key, oldValue: this.oldValue, newValue: this.newValue };\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.AttributeOperation';\n\t}\n\n\t/**\n\t * Creates `AttributeOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\treturn new AttributeOperation( Range.fromJSON( json.range, document ), json.key, json.oldValue, json.newValue, json.baseVersion );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/attributeoperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/moveoperation\n */\n\nimport Operation from './operation';\nimport Position from '../position';\nimport Range from '../range';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\nimport writer from './../writer';\n\n/**\n * Operation to move a range of {@link module:engine/model/item~Item model items}\n * to given {@link module:engine/model/position~Position target position}.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class MoveOperation extends Operation {\n\t/**\n\t * Creates a move operation.\n\t *\n\t * @param {module:engine/model/position~Position} sourcePosition\n\t * Position before the first {@link module:engine/model/item~Item model item} to move.\n\t * @param {Number} 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 {module:engine/model/position~Position} targetPosition Position at which moved nodes will be inserted.\n\t * @param {Number} baseVersion {@link module:engine/model/document~Document#version} on which operation can be applied.\n\t */\n\tconstructor( sourcePosition, howMany, targetPosition, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Position before the first {@link module:engine/model/item~Item model item} to move.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/moveoperation~MoveOperation#sourcePosition\n\t\t */\n\t\tthis.sourcePosition = Position.createFromPosition( sourcePosition );\n\n\t\t/**\n\t\t * Offset size of moved range.\n\t\t *\n\t\t * @member {Number} module:engine/model/operation/moveoperation~MoveOperation#howMany\n\t\t */\n\t\tthis.howMany = howMany;\n\n\t\t/**\n\t\t * Position at which moved nodes will be inserted.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/moveoperation~MoveOperation#targetPosition\n\t\t */\n\t\tthis.targetPosition = Position.createFromPosition( targetPosition );\n\n\t\t/**\n\t\t * Defines whether `MoveOperation` is sticky. If `MoveOperation` is sticky, during\n\t\t * {@link module:engine/model/operation/transform~transform operational transformation} if there will be an operation that\n\t\t * inserts some nodes at the position equal to the boundary of this `MoveOperation`, that operation will\n\t\t * get their insertion path updated to the position where this `MoveOperation` moves the range.\n\t\t *\n\t\t * @member {Boolean} module:engine/model/operation/moveoperation~MoveOperation#isSticky\n\t\t */\n\t\tthis.isSticky = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'move';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/moveoperation~MoveOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\tconst op = new this.constructor( this.sourcePosition, this.howMany, this.targetPosition, this.baseVersion );\n\t\top.isSticky = this.isSticky;\n\n\t\treturn op;\n\t}\n\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 *\t\t vv vv\n\t *\t\tabcdefg ===> adefbcg\n\t *\t\t ^ ^\n\t *\t\t targetPos\tmovedRangeStart\n\t *\t\t offset 6\toffset 4\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tgetMovedRangeStart() {\n\t\treturn this.targetPosition._getTransformedByDeletion( this.sourcePosition, this.howMany );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/moveoperation~MoveOperation}\n\t */\n\tgetReversed() {\n\t\tconst newTargetPosition = this.sourcePosition._getTransformedByInsertion( this.targetPosition, this.howMany );\n\n\t\tconst op = new this.constructor( this.getMovedRangeStart(), this.howMany, newTargetPosition, this.baseVersion + 1 );\n\t\top.isSticky = this.isSticky;\n\n\t\treturn op;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\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\n\t\t// Validate whether move operation has correct parameters.\n\t\t// Validation is pretty complex but move operation is one of the core ways to manipulate the document state.\n\t\t// We expect that many errors might be connected with one of scenarios described below.\n\t\tif ( !sourceElement || !targetElement ) {\n\t\t\t/**\n\t\t\t * Source position or target position is invalid.\n\t\t\t *\n\t\t\t * @error move-operation-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'move-operation-position-invalid: Source position or target position is invalid.'\n\t\t\t);\n\t\t} else if ( sourceOffset + this.howMany > sourceElement.maxOffset ) {\n\t\t\t/**\n\t\t\t * The nodes which should be moved do not exist.\n\t\t\t *\n\t\t\t * @error move-operation-nodes-do-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'move-operation-nodes-do-not-exist: The nodes which should be moved do not exist.'\n\t\t\t);\n\t\t} else if ( sourceElement === targetElement && sourceOffset < targetOffset && targetOffset < sourceOffset + this.howMany ) {\n\t\t\t/**\n\t\t\t * Trying to move a range of nodes into the middle of that range.\n\t\t\t *\n\t\t\t * @error move-operation-range-into-itself\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'move-operation-range-into-itself: Trying to move a range of nodes to the inside of that range.'\n\t\t\t);\n\t\t} else 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\n\t\t\t\tif ( this.targetPosition.path[ i ] >= sourceOffset && this.targetPosition.path[ i ] < sourceOffset + this.howMany ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Trying to move a range of nodes into one of nodes from that range.\n\t\t\t\t\t *\n\t\t\t\t\t * @error move-operation-node-into-itself\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t'move-operation-node-into-itself: Trying to move a range of nodes into one of nodes from that range.'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst range = writer.move( Range.createFromPositionAndShift( this.sourcePosition, this.howMany ), this.targetPosition );\n\n\t\treturn {\n\t\t\tsourcePosition: this.sourcePosition,\n\t\t\trange\n\t\t};\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.MoveOperation';\n\t}\n\n\t/**\n\t * Creates `MoveOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/moveoperation~MoveOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\tconst sourcePosition = Position.fromJSON( json.sourcePosition, document );\n\t\tconst targetPosition = Position.fromJSON( json.targetPosition, document );\n\n\t\tconst move = new this( sourcePosition, json.howMany, targetPosition, json.baseVersion );\n\n\t\tif ( json.isSticky ) {\n\t\t\tmove.isSticky = true;\n\t\t}\n\n\t\treturn move;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/moveoperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/reinsertoperation\n */\n\nimport MoveOperation from './moveoperation';\nimport RemoveOperation from './removeoperation';\n\n/**\n * Operation to reinsert previously removed nodes back to the non-graveyard root. This operation acts like\n * {@link module:engine/model/operation/moveoperation~MoveOperation} but it returns\n * {@link module:engine/model/operation/removeoperation~RemoveOperation} when reversed\n * and fires different change event.\n */\nexport default class ReinsertOperation extends MoveOperation {\n\t/**\n\t * Position where nodes will be re-inserted.\n\t *\n\t * @type {module:engine/model/position~Position}\n\t */\n\tget position() {\n\t\treturn this.targetPosition;\n\t}\n\n\t/**\n\t * @param {module:engine/model/position~Position} pos\n\t */\n\tset position( pos ) {\n\t\tthis.targetPosition = pos;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'reinsert';\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/removeoperation~RemoveOperation}\n\t */\n\tgetReversed() {\n\t\tconst newTargetPosition = this.sourcePosition._getTransformedByInsertion( this.targetPosition, this.howMany );\n\n\t\treturn new RemoveOperation( this.getMovedRangeStart(), this.howMany, newTargetPosition, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.ReinsertOperation';\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/reinsertoperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/removeoperation\n */\n\nimport MoveOperation from './moveoperation';\nimport ReinsertOperation from './reinsertoperation';\n\n/**\n * Operation to remove a range of nodes.\n */\nexport default class RemoveOperation extends MoveOperation {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'remove';\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/reinsertoperation~ReinsertOperation|module:engine/model/operation/nooperation~NoOperation}\n\t */\n\tgetReversed() {\n\t\tconst newTargetPosition = this.sourcePosition._getTransformedByInsertion( this.targetPosition, this.howMany );\n\n\t\treturn new ReinsertOperation( this.getMovedRangeStart(), this.howMany, newTargetPosition, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.RemoveOperation';\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/removeoperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/insertoperation\n */\n\nimport Operation from './operation';\nimport Position from '../position';\nimport NodeList from '../nodelist';\nimport RemoveOperation from './removeoperation';\nimport { insert, normalizeNodes } from '../writer';\nimport Text from '../text';\nimport Element from '../element';\n\n/**\n * Operation to insert one or more nodes at given position in the model.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class InsertOperation extends Operation {\n\t/**\n\t * Creates an insert operation.\n\t *\n\t * @param {module:engine/model/position~Position} position Position of insertion.\n\t * @param {module:engine/model/node~NodeSet} nodes The list of nodes to be inserted.\n\t * @param {Number} baseVersion {@link module:engine/model/document~Document#version} on which operation can be applied.\n\t */\n\tconstructor( position, nodes, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Position of insertion.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/insertoperation~InsertOperation#position\n\t\t */\n\t\tthis.position = Position.createFromPosition( position );\n\n\t\t/**\n\t\t * List of nodes to insert.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/nodelist~NodeList} module:engine/model/operation/insertoperation~InsertOperation#nodeList\n\t\t */\n\t\tthis.nodes = new NodeList( normalizeNodes( nodes ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'insert';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/insertoperation~InsertOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\tconst nodes = new NodeList( [ ...this.nodes ].map( node => node.clone( true ) ) );\n\n\t\treturn new InsertOperation( this.position, nodes, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/removeoperation~RemoveOperation}\n\t */\n\tgetReversed() {\n\t\tconst graveyard = this.position.root.document.graveyard;\n\t\tconst gyPosition = new Position( graveyard, [ 0 ] );\n\n\t\treturn new RemoveOperation( this.position, this.nodes.maxOffset, gyPosition, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\t// What happens here is that we want original nodes be passed to writer because we want original nodes\n\t\t// to be inserted to the model. But in InsertOperation, we want to keep those nodes as they were added\n\t\t// to the operation, not modified. For example, text nodes can get merged or cropped while Elements can\n\t\t// get children. It is important that InsertOperation has the copy of original nodes in intact state.\n\t\tconst originalNodes = this.nodes;\n\t\tthis.nodes = new NodeList( [ ...originalNodes ].map( node => node.clone( true ) ) );\n\n\t\tconst range = insert( this.position, originalNodes );\n\n\t\treturn { range };\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.InsertOperation';\n\t}\n\n\t/**\n\t * Creates `InsertOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/insertoperation~InsertOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\tconst children = [];\n\n\t\tfor ( const child of json.nodes ) {\n\t\t\tif ( child.name ) {\n\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t} else {\n\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t}\n\t\t}\n\n\t\treturn new InsertOperation( Position.fromJSON( json.position, document ), children, json.baseVersion );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/insertoperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/markeroperation\n */\n\nimport Operation from './operation';\nimport Range from '../range';\n\n/**\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class MarkerOperation extends Operation {\n\t/**\n\t * @param {String} name Marker name.\n\t * @param {module:engine/model/range~Range} oldRange Marker range before the change.\n\t * @param {module:engine/model/range~Range} newRange Marker range after the change.\n\t * @param {module:engine/model/markercollection~MarkerCollection} markers Marker collection on which change should be executed.\n\t * @param {Number} baseVersion {@link module:engine/model/document~Document#version} on which the operation can be applied.\n\t */\n\tconstructor( name, oldRange, newRange, markers, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Marker name.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Marker range before the change.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/range~Range}\n\t\t */\n\t\tthis.oldRange = oldRange ? Range.createFromRange( oldRange ) : null;\n\n\t\t/**\n\t\t * Marker range after the change.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/range~Range}\n\t\t */\n\t\tthis.newRange = newRange ? Range.createFromRange( newRange ) : null;\n\n\t\t/**\n\t\t * Marker collection on which change should be executed.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/markercollection~MarkerCollection}\n\t\t */\n\t\tthis._markers = markers;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'marker';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/markeroperation~MarkerOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new MarkerOperation( this.name, this.oldRange, this.newRange, this._markers, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/markeroperation~MarkerOperation}\n\t */\n\tgetReversed() {\n\t\treturn new MarkerOperation( this.name, this.newRange, this.oldRange, this._markers, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\tconst type = this.newRange ? 'set' : 'remove';\n\n\t\tthis._markers[ type ]( this.name, this.newRange );\n\n\t\treturn { name: this.name, type };\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tdelete json._markers;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.MarkerOperation';\n\t}\n\n\t/**\n\t * Creates `MarkerOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/markeroperation~MarkerOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\treturn new MarkerOperation(\n\t\t\tjson.name,\n\t\t\tjson.oldRange ? Range.fromJSON( json.oldRange, document ) : null,\n\t\t\tjson.newRange ? Range.fromJSON( json.newRange, document ) : null,\n\t\t\tdocument.markers,\n\t\t\tjson.baseVersion\n\t\t);\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/markeroperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/nooperation\n */\n\nimport Operation from './operation';\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 *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class NoOperation extends Operation {\n\tget type() {\n\t\treturn 'noop';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/nooperation~NoOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new NoOperation( this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/nooperation~NoOperation}\n\t */\n\tgetReversed() {\n\t\treturn new NoOperation( this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\treturn {};\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.NoOperation';\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/nooperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/renameoperation\n */\n\nimport Operation from './operation';\nimport Element from '../element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Position from '../position';\n\n/**\n * Operation to change element's name.\n *\n * Using this class you can change element's name.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class RenameOperation extends Operation {\n\t/**\n\t * Creates an operation that changes element's name.\n\t *\n\t * @param {module:engine/model/position~Position} position Position before an element to change.\n\t * @param {String} oldName Current name of the element.\n\t * @param {String} newName New name for the element.\n\t * @param {Number} baseVersion {@link module:engine/model/document~Document#version} on which the operation can be applied.\n\t */\n\tconstructor( position, oldName, newName, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Position before an element to change.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/renameoperation~RenameOperation#position\n\t\t */\n\t\tthis.position = position;\n\n\t\t/**\n\t\t * Current name of the element.\n\t\t *\n\t\t * @member {String} module:engine/model/operation/renameoperation~RenameOperation#oldName\n\t\t */\n\t\tthis.oldName = oldName;\n\n\t\t/**\n\t\t * New name for the element.\n\t\t *\n\t\t * @member {String} module:engine/model/operation/renameoperation~RenameOperation#newName\n\t\t */\n\t\tthis.newName = newName;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'rename';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/renameoperation~RenameOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new RenameOperation( Position.createFromPosition( this.position ), this.oldName, this.newName, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/renameoperation~RenameOperation}\n\t */\n\tgetReversed() {\n\t\treturn new RenameOperation( Position.createFromPosition( this.position ), this.newName, this.oldName, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\t// Validation.\n\t\tconst element = this.position.nodeAfter;\n\n\t\tif ( !( element instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Given position is invalid or node after it is not instance of Element.\n\t\t\t *\n\t\t\t * @error rename-operation-wrong-position\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rename-operation-wrong-position: Given position is invalid or node after it is not an instance of Element.'\n\t\t\t);\n\t\t} else if ( element.name !== this.oldName ) {\n\t\t\t/**\n\t\t\t * Element to change has different name than operation's old name.\n\t\t\t *\n\t\t\t * @error rename-operation-wrong-name\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rename-operation-wrong-name: Element to change has different name than operation\\'s old name.'\n\t\t\t);\n\t\t}\n\n\t\t// If value to set is same as old value, don't do anything.\n\t\tif ( element.name != this.newName ) {\n\t\t\t// Execution.\n\t\t\telement.name = this.newName;\n\t\t}\n\n\t\treturn { element, oldName: this.oldName };\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.RenameOperation';\n\t}\n\n\t/**\n\t * Creates `RenameOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\treturn new RenameOperation( Position.fromJSON( json.position, document ), json.oldName, json.newName, json.baseVersion );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/renameoperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/rootattributeoperation\n */\n\nimport Operation from './operation';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\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~Position} has to be inside a root.\n * {@link module:engine/model/position~Position} can't be created before a root element.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class RootAttributeOperation extends Operation {\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 {module:engine/model/rootelement~RootElement} root Root element to change.\n\t * @param {String} key Key of an attribute to change or remove.\n\t * @param {*} oldValue Old value of the attribute with given key or `null` if adding a new attribute.\n\t * @param {*} newValue New value to set for the attribute. If `null`, then the operation just removes the attribute.\n\t * @param {Number} baseVersion {@link module:engine/model/document~Document#version} on which the operation can be applied.\n\t */\n\tconstructor( root, key, oldValue, newValue, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Root element to change.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/rootelement~RootElement}\n\t\t */\n\t\tthis.root = root;\n\n\t\t/**\n\t\t * Key of an attribute to change or remove.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.key = key;\n\n\t\t/**\n\t\t * Old value of the attribute with given key or `null` if adding a new attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @member {*}\n\t\t */\n\t\tthis.oldValue = oldValue;\n\n\t\t/**\n\t\t * New value to set for the attribute. If `null`, then the operation just removes the attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @member {*}\n\t\t */\n\t\tthis.newValue = newValue;\n\t}\n\n\tget type() {\n\t\tif ( this.oldValue === null ) {\n\t\t\treturn 'addRootAttribute';\n\t\t} else if ( this.newValue === null ) {\n\t\t\treturn 'removeRootAttribute';\n\t\t} else {\n\t\t\treturn 'changeRootAttribute';\n\t\t}\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/rootattributeoperation~RootAttributeOperation} 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\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/rootattributeoperation~RootAttributeOperation}\n\t */\n\tgetReversed() {\n\t\treturn new RootAttributeOperation( this.root, this.key, this.newValue, this.oldValue, this.baseVersion + 1 );\n\t}\n\n\t_execute() {\n\t\tif ( this.oldValue !== null && this.root.getAttribute( this.key ) !== this.oldValue ) {\n\t\t\t/**\n\t\t\t * The attribute which should be removed does not exists for the given node.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-wrong-old-value\n\t\t\t * @param {module:engine/model/rootelement~RootElement} root\n\t\t\t * @param {String} key\n\t\t\t * @param {*} value\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-wrong-old-value: Changed node has different attribute value than operation\\'s ' +\n\t\t\t\t'old attribute value.',\n\t\t\t\t{ root: this.root, key: this.key }\n\t\t\t);\n\t\t}\n\n\t\tif ( this.oldValue === null && this.newValue !== null && this.root.hasAttribute( this.key ) ) {\n\t\t\t/**\n\t\t\t * The attribute with given key already exists for the given node.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-attribute-exists\n\t\t\t * @param {module:engine/model/rootelement~RootElement} root\n\t\t\t * @param {String} key\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-attribute-exists: The attribute with given key already exists.',\n\t\t\t\t{ root: this.root, key: this.key }\n\t\t\t);\n\t\t}\n\n\t\tif ( this.newValue !== null ) {\n\t\t\tthis.root.setAttribute( this.key, this.newValue );\n\t\t} else {\n\t\t\tthis.root.removeAttribute( this.key );\n\t\t}\n\n\t\treturn { root: this.root, key: this.key, oldValue: this.oldValue, newValue: this.newValue };\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.operation.RootAttributeOperation';\n\t}\n\n\t/**\n\t * Creates RootAttributeOperation object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/rootattributeoperation~RootAttributeOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\tif ( !document.hasRoot( json.root ) ) {\n\t\t\t/**\n\t\t\t * Cannot create RootAttributeOperation for document. Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error rootattributeoperation-fromjson-no-root\n\t\t\t * @param {String} rootName\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-fromjson-no-root: Cannot create RootAttributeOperation. Root with specified name does not exist.',\n\t\t\t\t{ rootName: json }\n\t\t\t);\n\t\t}\n\n\t\treturn new RootAttributeOperation( document.getRoot( json.root ), json.key, json.oldValue, json.newValue, json.baseVersion );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/rootattributeoperation.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/operationfactory\n */\n\nimport AttributeOperation from '../operation/attributeoperation';\nimport InsertOperation from '../operation/insertoperation';\nimport MarkerOperation from '../operation/markeroperation';\nimport MoveOperation from '../operation/moveoperation';\nimport NoOperation from '../operation/nooperation';\nimport Operation from '../operation/operation';\nimport ReinsertOperation from '../operation/reinsertoperation';\nimport RemoveOperation from '../operation/removeoperation';\nimport RenameOperation from '../operation/renameoperation';\nimport RootAttributeOperation from '../operation/rootattributeoperation';\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[ ReinsertOperation.className ] = ReinsertOperation;\noperations[ RemoveOperation.className ] = RemoveOperation;\noperations[ RenameOperation.className ] = RenameOperation;\noperations[ RootAttributeOperation.className ] = RootAttributeOperation;\n\n/**\n * A factory class for creating operations.\n *\n * @abstract\n */\nexport default class OperationFactory {\n\t/**\n\t * Creates concrete `Operation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/operation~Operation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\treturn operations[ json.__className ].fromJSON( json, document );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/operation/operationfactory.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/deltafactory\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\nimport OperationFactory from '../operation/operationfactory';\n\nconst deserializers = new Map();\n\n/**\n * A factory class for creating operations.\n *\n * Delta is a single, from the user action point of view, change in the editable document, like insert, split or\n * rename element. Delta is composed of operations, which are unit changes needed to be done to execute user action.\n *\n * Multiple deltas are grouped into a single {@link module:engine/model/batch~Batch}.\n */\nexport default class DeltaFactory {\n\t/**\n\t * Creates InsertDelta from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json\n\t * @param {module:engine/model/document~Document} doc Document on which this delta will be applied.\n\t * @returns {module:engine/model/delta/insertdelta~InsertDelta}\n\t */\n\tstatic fromJSON( json, doc ) {\n\t\tif ( !deserializers.has( json.__className ) ) {\n\t\t\t/**\n\t\t\t * This delta has no defined deserializer.\n\t\t\t *\n\t\t\t * @error delta-fromjson-no-deserializer\n\t\t\t * @param {String} name\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'delta-fromjson-no-deserializer: This delta has no defined deserializer',\n\t\t\t\t{ name: json.__className }\n\t\t\t);\n\t\t}\n\n\t\tconst Delta = deserializers.get( json.__className );\n\n\t\tconst delta = new Delta();\n\n\t\tfor ( const operation of json.operations ) {\n\t\t\tdelta.addOperation( OperationFactory.fromJSON( operation, doc ) );\n\t\t}\n\n\t\t// Rewrite all other properties.\n\t\tfor ( const prop in json ) {\n\t\t\tif ( prop != '__className' && delta[ prop ] === undefined ) {\n\t\t\t\tdelta[ prop ] = json[ prop ];\n\t\t\t}\n\t\t}\n\n\t\treturn delta;\n\t}\n\n\t/**\n\t * Registers a class for delta factory.\n\t *\n\t * @param {Function} Delta A delta class to register.\n\t */\n\tstatic register( Delta ) {\n\t\tdeserializers.set( Delta.className, Delta );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/deltafactory.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/delta\n */\n\nimport clone from '@ckeditor/ckeditor5-utils/src/lib/lodash/clone';\nimport DeltaFactory from './deltafactory';\n\n/**\n * Base class for all deltas.\n *\n * Delta is a single, from the user action point of view, change in the editable document, like insert, split or\n * rename element. Delta is composed of operations, which are unit changes needed to be done to execute user action.\n *\n * Multiple deltas are grouped into a single {@link module:engine/model/batch~Batch}.\n */\nexport default class Delta {\n\t/**\n\t * Creates a delta instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * {@link module:engine/model/batch~Batch} which delta is a part of. This property is null by default and set by the\n\t\t * {@link module:engine/model/batch~Batch#addDelta} method.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/batch~Batch} module:engine/model/delta/delta~Delta#batch\n\t\t */\n\t\tthis.batch = null;\n\n\t\t/**\n\t\t * Array of operations which compose delta.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/operation/operation~Operation[]} module:engine/model/delta/delta~Delta#operations\n\t\t */\n\t\tthis.operations = [];\n\t}\n\n\t/**\n\t * Returns delta base version which is equal to the base version of the first operation in delta. If there\n\t * are no operations in delta, returns `null`.\n\t *\n\t * @see module:engine/model/document~Document\n\t * @type {Number|null}\n\t */\n\tget baseVersion() {\n\t\tif ( this.operations.length > 0 ) {\n\t\t\treturn this.operations[ 0 ].baseVersion;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * @param {Number} baseVersion\n\t */\n\tset baseVersion( baseVersion ) {\n\t\tfor ( const operation of this.operations ) {\n\t\t\toperation.baseVersion = baseVersion++;\n\t\t}\n\t}\n\n\t/**\n\t * A class that will be used when creating reversed delta.\n\t *\n\t * @private\n\t * @type {Function}\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn Delta;\n\t}\n\n\t/**\n\t * Delta type.\n\t *\n\t * @readonly\n\t * @member {String} #type\n\t */\n\n\t/**\n\t * Add operation to the delta.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation Operation instance.\n\t */\n\taddOperation( operation ) {\n\t\toperation.delta = this;\n\t\tthis.operations.push( operation );\n\n\t\treturn operation;\n\t}\n\n\t/**\n\t * Creates and returns a delta that has the same parameters as this delta.\n\t *\n\t * @returns {module:engine/model/delta/delta~Delta} Clone of this delta.\n\t */\n\tclone() {\n\t\tconst delta = new this.constructor();\n\n\t\tfor ( const op of this.operations ) {\n\t\t\tdelta.addOperation( op.clone() );\n\t\t}\n\n\t\treturn delta;\n\t}\n\n\t/**\n\t * Creates and returns a reverse delta. Reverse delta when executed right after the original delta will bring back\n\t * tree model state to the point before the original delta execution. In other words, it reverses changes done\n\t * by the original delta.\n\t *\n\t * Keep in mind that tree model state may change since executing the original delta, so reverse delta may be \"outdated\".\n\t * In that case you will need to {@link module:engine/model/delta/transform~transform} it by all deltas that were executed after\n\t * the original delta.\n\t *\n\t * @returns {module:engine/model/delta/delta~Delta} Reversed delta.\n\t */\n\tgetReversed() {\n\t\tconst delta = new this._reverseDeltaClass();\n\n\t\tfor ( const op of this.operations ) {\n\t\t\tdelta.addOperation( op.getReversed() );\n\t\t}\n\n\t\tdelta.operations.reverse();\n\n\t\tfor ( let i = 0; i < delta.operations.length; i++ ) {\n\t\t\tdelta.operations[ i ].baseVersion = this.operations[ this.operations.length - 1 ].baseVersion + i + 1;\n\t\t}\n\n\t\treturn delta;\n\t}\n\n\t/**\n\t * Custom toJSON method to make deltas serializable.\n\t *\n\t * @returns {Object} Clone of this delta with added class name.\n\t */\n\ttoJSON() {\n\t\tconst json = clone( this );\n\n\t\tjson.__className = this.constructor.className;\n\n\t\t// Remove parent batch to avoid circular dependencies.\n\t\tdelete json.batch;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Delta class name. Used by {@link #toJSON} method for serialization and\n\t * {@link module:engine/model/delta/deltafactory~DeltaFactory.fromJSON} during deserialization.\n\t *\n\t * @type {String}\n\t * @readonly\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.Delta';\n\t}\n}\n\nDeltaFactory.register( Delta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/delta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/insertdelta\n */\n\nimport Delta from './delta';\nimport RemoveDelta from './removedelta';\nimport DeltaFactory from './deltafactory';\nimport InsertOperation from '../operation/insertoperation';\nimport { register } from '../batch';\nimport { normalizeNodes } from './../writer';\n\nimport DocumentFragment from '../documentfragment';\nimport Range from '../../model/range.js';\nimport Position from '../../model/position.js';\n\n/**\n * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#insert Batch#insert} method\n * uses the `InsertDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class InsertDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'insert';\n\t}\n\n\t/**\n\t * Position where the delta inserts nodes or `null` if there are no operations in the delta.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget position() {\n\t\treturn this._insertOperation ? this._insertOperation.position : null;\n\t}\n\n\t/**\n\t * Node list containing all the nodes inserted by the delta or `null` if there are no operations in the delta.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/nodelist~NodeList|null}\n\t */\n\tget nodes() {\n\t\treturn this._insertOperation ? this._insertOperation.nodes : null;\n\t}\n\n\t/**\n\t * Insert operation that is saved in this delta or `null` if there are no operations in the delta.\n\t *\n\t * @readonly\n\t * @protected\n\t * @type {module:engine/model/operation/insertoperation~InsertOperation|null}\n\t */\n\tget _insertOperation() {\n\t\treturn this.operations[ 0 ] || null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn RemoveDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.InsertDelta';\n\t}\n}\n\n/**\n * Inserts a node or nodes at the given position.\n *\n * When inserted element is a {@link module:engine/model/documentfragment~DocumentFragment} and has markers its markers will\n * be set to {@link module:engine/model/document~Document#markers}.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#insert\n * @param {module:engine/model/position~Position} position Position of insertion.\n * @param {module:engine/model/node~NodeSet} nodes The list of nodes to be inserted.\n */\nregister( 'insert', function( position, nodes ) {\n\tconst normalizedNodes = normalizeNodes( nodes );\n\n\t// If nothing is inserted do not create delta and operation.\n\tif ( normalizedNodes.length === 0 ) {\n\t\treturn this;\n\t}\n\n\tconst delta = new InsertDelta();\n\tconst insert = new InsertOperation( position, normalizedNodes, this.document.version );\n\n\tthis.addDelta( delta );\n\tdelta.addOperation( insert );\n\tthis.document.applyOperation( insert );\n\n\t// When element is a DocumentFragment we need to move its markers to Document#markers.\n\tif ( nodes instanceof DocumentFragment ) {\n\t\tfor ( const [ markerName, markerRange ] of nodes.markers ) {\n\t\t\t// We need to migrate marker range from DocumentFragment to Document.\n\t\t\tconst rangeRootPosition = Position.createAt( markerRange.root );\n\t\t\tconst range = new Range(\n\t\t\t\tmarkerRange.start._getCombined( rangeRootPosition, position ),\n\t\t\t\tmarkerRange.end._getCombined( rangeRootPosition, position )\n\t\t\t);\n\n\t\t\tthis.setMarker( markerName, range );\n\t\t}\n\t}\n\n\treturn this;\n} );\n\nDeltaFactory.register( InsertDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/insertdelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/splitdelta\n */\n\nimport Delta from './delta';\nimport DeltaFactory from './deltafactory';\nimport { register } from '../batch';\nimport Position from '../position';\nimport Element from '../element';\nimport InsertOperation from '../operation/insertoperation';\nimport MoveOperation from '../operation/moveoperation';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport MergeDelta from '../delta/mergedelta';\n\n/**\n * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#split} method\n * uses `SplitDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class SplitDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'split';\n\t}\n\n\t/**\n\t * Position of split or `null` if there are no operations in the delta.\n\t *\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget position() {\n\t\treturn this._moveOperation ? this._moveOperation.sourcePosition : null;\n\t}\n\n\t/**\n\t * Operation in the delta that adds to model an element into which split nodes will be moved, or `null` if\n\t * there are no operations in the delta.\n\t *\n\t * Most commonly this will be {@link module:engine/model/operation/insertoperation~InsertOperation an insert operation},\n\t * as `SplitDelta` has to create a new node. If `SplitDelta` was created through\n\t * {@link module:engine/model/delta/delta~Delta#getReversed reversing}\n\t * a {@link module:engine/model/delta/mergedelta~MergeDelta merge delta},\n\t * this will be a {@link module:engine/model/operation/reinsertoperation~ReinsertOperation reinsert operation},\n\t * as we will want to re-insert the exact element that was removed by that merge delta.\n\t *\n\t * @protected\n\t * @type {module:engine/model/operation/insertoperation~InsertOperation|\n\t * module:engine/model/operation/reinsertoperation~ReinsertOperation|null}\n\t */\n\tget _cloneOperation() {\n\t\treturn this.operations[ 0 ] || null;\n\t}\n\n\t/**\n\t * Operation in the delta that moves model items, that are after split position, to their new parent or `null`\n\t * if there are no operations in the delta.\n\t *\n\t * @protected\n\t * @type {module:engine/model/operation/moveoperation~MoveOperation|null}\n\t */\n\tget _moveOperation() {\n\t\treturn this.operations[ 1 ] && this.operations[ 1 ] instanceof MoveOperation ? this.operations[ 1 ] : null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn MergeDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.SplitDelta';\n\t}\n}\n\n/**\n * Splits an element at the given position.\n *\n * The element cannot be a root element, as root element cannot be split. The `batch-split-root` error will be thrown if\n * you try to split the root element.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#split\n * @param {module:engine/model/position~Position} position Position of split.\n */\nregister( 'split', function( position ) {\n\tconst delta = new SplitDelta();\n\tthis.addDelta( delta );\n\n\tconst splitElement = position.parent;\n\n\tif ( !splitElement.parent ) {\n\t\t/**\n\t\t * Root element can not be split.\n\t\t *\n\t\t * @error batch-split-root\n\t\t */\n\t\tthrow new CKEditorError( 'batch-split-root: Root element can not be split.' );\n\t}\n\n\tconst copy = new Element( splitElement.name, splitElement.getAttributes() );\n\n\tconst insert = new InsertOperation(\n\t\tPosition.createAfter( splitElement ),\n\t\tcopy,\n\t\tthis.document.version\n\t);\n\n\tdelta.addOperation( insert );\n\tthis.document.applyOperation( insert );\n\n\tconst move = new MoveOperation(\n\t\tposition,\n\t\tsplitElement.maxOffset - position.offset,\n\t\tPosition.createFromParentAndOffset( copy, 0 ),\n\t\tthis.document.version\n\t);\n\tmove.isSticky = true;\n\n\tdelta.addOperation( move );\n\tthis.document.applyOperation( move );\n\n\treturn this;\n} );\n\nDeltaFactory.register( SplitDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/splitdelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/mergedelta\n */\n\nimport Delta from './delta';\nimport DeltaFactory from './deltafactory';\nimport SplitDelta from './splitdelta';\nimport { register } from '../batch';\nimport Position from '../position';\nimport Element from '../element';\nimport RemoveOperation from '../operation/removeoperation';\nimport MoveOperation from '../operation/moveoperation';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#merge} method\n * uses the `MergeDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class MergeDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'merge';\n\t}\n\n\t/**\n\t * Position between to merged nodes or `null` if the delta has no operations.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget position() {\n\t\treturn this._removeOperation ? this._removeOperation.sourcePosition : null;\n\t}\n\n\t/**\n\t * Operation in this delta that removes the node after merge position (which will be empty at that point) or\n\t * `null` if the delta has no operations. Note, that after {@link module:engine/model/delta/transform~transform transformation}\n\t * this might be an instance of {@link module:engine/model/operation/moveoperation~MoveOperation} instead of\n\t * {@link module:engine/model/operation/removeoperation~RemoveOperation}.\n\t *\n\t * @readonly\n\t * @protected\n\t * @type {module:engine/model/operation/moveoperation~MoveOperation|null}\n\t */\n\tget _removeOperation() {\n\t\treturn this.operations[ 1 ] || null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn SplitDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.MergeDelta';\n\t}\n}\n\n/**\n * Merges two siblings at the given position.\n *\n * Node before and after the position have to be an element. Otherwise `batch-merge-no-element-before` or\n * `batch-merge-no-element-after` error will be thrown.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#merge\n * @param {module:engine/model/position~Position} position Position of merge.\n */\nregister( 'merge', function( position ) {\n\tconst delta = new MergeDelta();\n\tthis.addDelta( delta );\n\n\tconst nodeBefore = position.nodeBefore;\n\tconst nodeAfter = position.nodeAfter;\n\n\tif ( !( nodeBefore instanceof Element ) ) {\n\t\t/**\n\t\t * Node before merge position must be an element.\n\t\t *\n\t\t * @error batch-merge-no-element-before\n\t\t */\n\t\tthrow new CKEditorError( 'batch-merge-no-element-before: Node before merge position must be an element.' );\n\t}\n\n\tif ( !( nodeAfter instanceof Element ) ) {\n\t\t/**\n\t\t * Node after merge position must be an element.\n\t\t *\n\t\t * @error batch-merge-no-element-after\n\t\t */\n\t\tthrow new CKEditorError( 'batch-merge-no-element-after: Node after merge position must be an element.' );\n\t}\n\n\tconst positionAfter = Position.createFromParentAndOffset( nodeAfter, 0 );\n\tconst positionBefore = Position.createFromParentAndOffset( nodeBefore, nodeBefore.maxOffset );\n\n\tconst move = new MoveOperation(\n\t\tpositionAfter,\n\t\tnodeAfter.maxOffset,\n\t\tpositionBefore,\n\t\tthis.document.version\n\t);\n\n\tmove.isSticky = true;\n\tdelta.addOperation( move );\n\tthis.document.applyOperation( move );\n\n\tconst graveyard = this.document.graveyard;\n\tconst gyPosition = new Position( graveyard, [ 0 ] );\n\n\tconst remove = new RemoveOperation( position, 1, gyPosition, this.document.version );\n\tdelta.addOperation( remove );\n\tthis.document.applyOperation( remove );\n\n\treturn this;\n} );\n\nDeltaFactory.register( MergeDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/mergedelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/wrapdelta\n */\n\nimport Delta from './delta';\nimport DeltaFactory from './deltafactory';\nimport UnwrapDelta from './unwrapdelta';\nimport { register } from '../batch';\nimport Position from '../position';\nimport Range from '../range';\nimport Element from '../element';\nimport InsertOperation from '../operation/insertoperation';\nimport MoveOperation from '../operation/moveoperation';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#merge} method\n * uses the `WrapDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class WrapDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'wrap';\n\t}\n\n\t/**\n\t * Range to wrap or `null` if there are no operations in the delta.\n\t *\n\t * @type {module:engine/model/range~Range|null}\n\t */\n\tget range() {\n\t\tconst moveOp = this._moveOperation;\n\n\t\treturn moveOp ? Range.createFromPositionAndShift( moveOp.sourcePosition, moveOp.howMany ) : null;\n\t}\n\n\t/**\n\t * Offset size of range to wrap by the delta or `null` if there are no operations in delta.\n\t *\n\t * @type {Number}\n\t */\n\tget howMany() {\n\t\tconst range = this.range;\n\n\t\treturn range ? range.end.offset - range.start.offset : 0;\n\t}\n\n\t/* eslint-disable max-len */\n\t/**\n\t * Operation that inserts wrapping element or `null` if there are no operations in the delta.\n\t *\n\t * @protected\n\t * @type {module:engine/model/operation/insertoperation~InsertOperation|module:engine/model/operation/reinsertoperation~ReinsertOperation}\n\t */\n\t/* eslint-enable max-len */\n\tget _insertOperation() {\n\t\treturn this.operations[ 0 ] || null;\n\t}\n\n\t/**\n\t * Operation that moves wrapped nodes to their new parent or `null` if there are no operations in the delta.\n\t *\n\t * @protected\n\t * @type {module:engine/model/operation/moveoperation~MoveOperation|null}\n\t */\n\tget _moveOperation() {\n\t\treturn this.operations[ 1 ] || null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn UnwrapDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.WrapDelta';\n\t}\n}\n\n/**\n * Wraps given range with given element or with a new element with specified name, if string has been passed.\n * **Note:** range to wrap should be a \"flat range\" (see {@link module:engine/model/range~Range#isFlat}). If not, error will be thrown.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#wrap\n * @param {module:engine/model/range~Range} range Range to wrap.\n * @param {module:engine/model/element~Element|String} elementOrString Element or name of element to wrap the range with.\n */\nregister( 'wrap', function( range, elementOrString ) {\n\tif ( !range.isFlat ) {\n\t\t/**\n\t\t * Range to wrap is not flat.\n\t\t *\n\t\t * @error batch-wrap-range-not-flat\n\t\t */\n\t\tthrow new CKEditorError( 'batch-wrap-range-not-flat: Range to wrap is not flat.' );\n\t}\n\n\tconst element = elementOrString instanceof Element ? elementOrString : new Element( elementOrString );\n\n\tif ( element.childCount > 0 ) {\n\t\t/**\n\t\t * Element to wrap with is not empty.\n\t\t *\n\t\t * @error batch-wrap-element-not-empty\n\t\t */\n\t\tthrow new CKEditorError( 'batch-wrap-element-not-empty: Element to wrap with is not empty.' );\n\t}\n\n\tif ( element.parent !== null ) {\n\t\t/**\n\t\t * Element to wrap with is already attached to a tree model.\n\t\t *\n\t\t * @error batch-wrap-element-attached\n\t\t */\n\t\tthrow new CKEditorError( 'batch-wrap-element-attached: Element to wrap with is already attached to tree model.' );\n\t}\n\n\tconst delta = new WrapDelta();\n\tthis.addDelta( delta );\n\n\tconst insert = new InsertOperation( range.end, element, this.document.version );\n\tdelta.addOperation( insert );\n\tthis.document.applyOperation( insert );\n\n\tconst targetPosition = Position.createFromParentAndOffset( element, 0 );\n\tconst move = new MoveOperation(\n\t\trange.start,\n\t\trange.end.offset - range.start.offset,\n\t\ttargetPosition,\n\t\tthis.document.version\n\t);\n\tdelta.addOperation( move );\n\tthis.document.applyOperation( move );\n\n\treturn this;\n} );\n\nDeltaFactory.register( WrapDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/wrapdelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/unwrapdelta\n */\n\nimport Delta from './delta';\nimport DeltaFactory from './deltafactory';\nimport WrapDelta from './wrapdelta';\nimport { register } from '../batch';\nimport Position from '../position';\nimport RemoveOperation from '../operation/removeoperation';\nimport MoveOperation from '../operation/moveoperation';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#merge} method\n * uses the `UnwrapDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class UnwrapDelta extends Delta {\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'unwrap';\n\t}\n\n\t/**\n\t * Position before unwrapped element or `null` if there are no operations in the delta.\n\t *\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget position() {\n\t\treturn this._moveOperation ? this._moveOperation.targetPosition : null;\n\t}\n\n\t/**\n\t * Operation in the delta that moves unwrapped nodes to their new parent or `null` if there are no operations in the delta.\n\t *\n\t * @protected\n\t * @type {module:engine/model/operation/moveoperation~MoveOperation|null}\n\t */\n\tget _moveOperation() {\n\t\treturn this.operations[ 0 ] || null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget _reverseDeltaClass() {\n\t\treturn WrapDelta;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.UnwrapDelta';\n\t}\n}\n\n/**\n * Unwraps children of the given element all its children are moved before it and then the element is removed.\n * Throws error if you try to unwrap an element which does not have a parent.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#unwrap\n * @param {module:engine/model/element~Element} position Element to unwrap.\n */\nregister( 'unwrap', function( element ) {\n\tif ( element.parent === null ) {\n\t\t/**\n\t\t * Trying to unwrap an element which has no parent.\n\t\t *\n\t\t * @error batch-unwrap-element-no-parent\n\t\t */\n\t\tthrow new CKEditorError( 'batch-unwrap-element-no-parent: Trying to unwrap an element which has no parent.' );\n\t}\n\n\tconst delta = new UnwrapDelta();\n\tthis.addDelta( delta );\n\n\tconst sourcePosition = Position.createFromParentAndOffset( element, 0 );\n\n\tconst move = new MoveOperation(\n\t\tsourcePosition,\n\t\telement.maxOffset,\n\t\tPosition.createBefore( element ),\n\t\tthis.document.version\n\t);\n\n\tmove.isSticky = true;\n\tdelta.addOperation( move );\n\tthis.document.applyOperation( move );\n\n\t// Computing new position because we moved some nodes before `element`.\n\t// If we would cache `Position.createBefore( element )` we remove wrong node.\n\tconst graveyard = this.document.graveyard;\n\tconst gyPosition = new Position( graveyard, [ 0 ] );\n\n\tconst remove = new RemoveOperation( Position.createBefore( element ), 1, gyPosition, this.document.version );\n\tdelta.addOperation( remove );\n\tthis.document.applyOperation( remove );\n\n\treturn this;\n} );\n\nDeltaFactory.register( UnwrapDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/unwrapdelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/weakinsertdelta\n */\n\nimport InsertDelta from './insertdelta';\nimport { register } from '../batch';\nimport DeltaFactory from './deltafactory';\nimport InsertOperation from '../operation/insertoperation';\nimport { normalizeNodes } from './../writer';\n\n/**\n * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#insert} method\n * uses the `WeakInsertDelta` class which inherits from the `Delta` class and may overwrite some methods.\n *\n * @extends module:engine/model/delta/delta~Delta\n */\nexport default class WeakInsertDelta extends InsertDelta {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'engine.model.delta.WeakInsertDelta';\n\t}\n}\n\n/**\n * Inserts a node or nodes at given position. {@link module:engine/model/batch~Batch#weakInsert weakInsert} is commonly used for actions\n * like typing or plain-text paste (without formatting). There are two differences between\n * {@link module:engine/model/batch~Batch#insert insert} and {@link module:engine/model/batch~Batch#weakInsert weakInsert}:\n *\n * * When using `weakInsert`, inserted nodes will have same attributes as the current attributes of\n * {@link module:engine/model/document~Document#selection document selection}.\n * * If {@link module:engine/model/operation/insertoperation~InsertOperation insert operation} position is inside a range changed by\n * {@link module:engine/model/operation/attributeoperation~AttributeOperation attribute operation},\n * the attribute operation is split into two operations.\n * Thanks to this, attribute change \"omits\" the inserted nodes. The correct behavior for `WeakInsertDelta` is that\n * {@link module:engine/model/operation/attributeoperation~AttributeOperation AttributeOperation} does not \"break\" and also\n * applies attributes for inserted nodes. This behavior has to be reflected during\n * {@link module:engine/model/delta/transform~transform delta transformation}.\n *\n * @chainable\n * @method module:engine/model/batch~Batch#weakInsert\n * @param {module:engine/model/position~Position} position Position of insertion.\n * @param {module:engine/model/node~NodeSet} nodes The list of nodes to be inserted.\n */\nregister( 'weakInsert', function( position, nodes ) {\n\tconst delta = new WeakInsertDelta();\n\tthis.addDelta( delta );\n\n\tnodes = normalizeNodes( nodes );\n\n\tfor ( const node of nodes ) {\n\t\tnode.setAttributesTo( this.document.selection.getAttributes() );\n\t}\n\n\tconst operation = new InsertOperation( position, nodes, this.document.version );\n\tdelta.addOperation( operation );\n\tthis.document.applyOperation( operation );\n\n\treturn this;\n} );\n\nDeltaFactory.register( WeakInsertDelta );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/weakinsertdelta.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/delta/basic-deltas\n */\n\n// Deltas require `register` method that require `Batch` class and is defined in batch-base.js.\n// We would like to group all deltas files in one place, so we would only have to include batch.js\n// which would already have all default deltas registered.\n\n// Import default suite of deltas so a feature have to include only Batch class file.\nimport './attributedelta';\nimport './insertdelta';\nimport './mergedelta';\nimport './movedelta';\nimport './removedelta';\nimport './renamedelta';\nimport './splitdelta';\nimport './unwrapdelta';\nimport './weakinsertdelta';\nimport './wrapdelta';\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/delta/basic-deltas.js\n// module id = null\n// module chunks = ","import baseSlice from './_baseSlice';\nimport isIterateeCall from './_isIterateeCall';\nimport toInteger from './toInteger';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeCeil = Math.ceil,\n nativeMax = Math.max;\n\n/**\n * Creates an array of elements split into groups the length of `size`.\n * If `array` can't be split evenly, the final chunk will be the remaining\n * elements.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to process.\n * @param {number} [size=1] The length of each chunk\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the new array of chunks.\n * @example\n *\n * _.chunk(['a', 'b', 'c', 'd'], 2);\n * // => [['a', 'b'], ['c', 'd']]\n *\n * _.chunk(['a', 'b', 'c', 'd'], 3);\n * // => [['a', 'b', 'c'], ['d']]\n */\nfunction chunk(array, size, guard) {\n if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {\n size = 1;\n } else {\n size = nativeMax(toInteger(size), 0);\n }\n var length = array ? array.length : 0;\n if (!length || size < 1) {\n return [];\n }\n var index = 0,\n resIndex = 0,\n result = Array(nativeCeil(length / size));\n\n while (index < length) {\n result[resIndex++] = baseSlice(array, index, (index += size));\n }\n return result;\n}\n\nexport default chunk;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/chunk.js\n// module id = null\n// module chunks = ","import isArguments from './isArguments';\nimport isArray from './isArray';\n\n/**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\nfunction isFlattenable(value) {\n return isArray(value) || isArguments(value);\n}\n\nexport default isFlattenable;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_isFlattenable.js\n// module id = null\n// module chunks = ","import arrayPush from './_arrayPush';\nimport baseFlatten from './_baseFlatten';\nimport copyArray from './_copyArray';\nimport isArray from './isArray';\n\n/**\n * Creates a new array concatenating `array` with any additional arrays\n * and/or values.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to concatenate.\n * @param {...*} [values] The values to concatenate.\n * @returns {Array} Returns the new concatenated array.\n * @example\n *\n * var array = [1];\n * var other = _.concat(array, 2, [3], [[4]]);\n *\n * console.log(other);\n * // => [1, 2, 3, [4]]\n *\n * console.log(array);\n * // => [1]\n */\nfunction concat() {\n var length = arguments.length,\n args = Array(length ? length - 1 : 0),\n array = arguments[0],\n index = length;\n\n while (index--) {\n args[index - 1] = arguments[index];\n }\n return length\n ? arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1))\n : [];\n}\n\nexport default concat;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/concat.js\n// module id = null\n// module chunks = ","import indexOfNaN from './_indexOfNaN';\n\n/**\n * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n *\n * @private\n * @param {Array} array The array to search.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseIndexOf(array, value, fromIndex) {\n if (value !== value) {\n return indexOfNaN(array, fromIndex);\n }\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseIndexOf;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseIndexOf.js\n// module id = null\n// module chunks = ","/**\n * Gets the index at which the first occurrence of `NaN` is found in `array`.\n *\n * @private\n * @param {Array} array The array to search.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched `NaN`, else `-1`.\n */\nfunction indexOfNaN(array, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 0 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n var other = array[index];\n if (other !== other) {\n return index;\n }\n }\n return -1;\n}\n\nexport default indexOfNaN;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_indexOfNaN.js\n// module id = null\n// module chunks = ","import baseIndexOf from './_baseIndexOf';\n\n/**\n * A specialized version of `_.includes` for arrays without support for\n * specifying an index to search from.\n *\n * @private\n * @param {Array} array The array to search.\n * @param {*} target The value to search for.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\nfunction arrayIncludes(array, value) {\n return !!array.length && baseIndexOf(array, value, 0) > -1;\n}\n\nexport default arrayIncludes;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_arrayIncludes.js\n// module id = null\n// module chunks = ","/**\n * This function is like `arrayIncludes` except that it accepts a comparator.\n *\n * @private\n * @param {Array} array The array to search.\n * @param {*} target The value to search for.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\nfunction arrayIncludesWith(array, value, comparator) {\n var index = -1,\n length = array.length;\n\n while (++index < length) {\n if (comparator(value, array[index])) {\n return true;\n }\n }\n return false;\n}\n\nexport default arrayIncludesWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_arrayIncludesWith.js\n// module id = null\n// module chunks = ","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_arrayMap.js\n// module id = null\n// module chunks = ","/**\n * The base implementation of `_.unary` without support for storing wrapper metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseUnary.js\n// module id = null\n// module chunks = ","/**\n * Checks if a cache value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_cacheHas.js\n// module id = null\n// module chunks = ","import SetCache from './_SetCache';\nimport arrayIncludes from './_arrayIncludes';\nimport arrayIncludesWith from './_arrayIncludesWith';\nimport arrayMap from './_arrayMap';\nimport baseUnary from './_baseUnary';\nimport cacheHas from './_cacheHas';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * The base implementation of methods like `_.difference` without support\n * for excluding multiple arrays or iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Array} values The values to exclude.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n */\nfunction baseDifference(array, values, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n isCommon = true,\n length = array.length,\n result = [],\n valuesLength = values.length;\n\n if (!length) {\n return result;\n }\n if (iteratee) {\n values = arrayMap(values, baseUnary(iteratee));\n }\n if (comparator) {\n includes = arrayIncludesWith;\n isCommon = false;\n }\n else if (values.length >= LARGE_ARRAY_SIZE) {\n includes = cacheHas;\n isCommon = false;\n values = new SetCache(values);\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var valuesIndex = valuesLength;\n while (valuesIndex--) {\n if (values[valuesIndex] === computed) {\n continue outer;\n }\n }\n result.push(value);\n }\n else if (!includes(values, computed, comparator)) {\n result.push(value);\n }\n }\n return result;\n}\n\nexport default baseDifference;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseDifference.js\n// module id = null\n// module chunks = ","import baseDifference from './_baseDifference';\nimport baseFlatten from './_baseFlatten';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport rest from './rest';\n\n/**\n * Creates an array of unique `array` values not included in the other given\n * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons. The order of result values is determined by the\n * order they occur in the first array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.without, _.xor\n * @example\n *\n * _.difference([3, 2, 1], [4, 2]);\n * // => [3, 1]\n */\nvar difference = rest(function(array, values) {\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))\n : [];\n});\n\nexport default difference;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/difference.js\n// module id = null\n// module chunks = ","import Stack from './_Stack';\nimport baseIsEqual from './_baseIsEqual';\n\n/** Used to compose bitmasks for comparison styles. */\nvar UNORDERED_COMPARE_FLAG = 1,\n PARTIAL_COMPARE_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport default baseIsMatch;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseIsMatch.js\n// module id = null\n// module chunks = ","import isObject from './isObject';\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nexport default isStrictComparable;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_isStrictComparable.js\n// module id = null\n// module chunks = ","import arrayMap from './_arrayMap';\n\n/**\n * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array\n * of key-value pairs for `object` corresponding to the property names of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the key-value pairs.\n */\nfunction baseToPairs(object, props) {\n return arrayMap(props, function(key) {\n return [key, object[key]];\n });\n}\n\nexport default baseToPairs;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseToPairs.js\n// module id = null\n// module chunks = ","/**\n * Converts `set` to its value-value pairs.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the value-value pairs.\n */\nfunction setToPairs(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = [value, value];\n });\n return result;\n}\n\nexport default setToPairs;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_setToPairs.js\n// module id = null\n// module chunks = ","import baseToPairs from './_baseToPairs';\nimport getTag from './_getTag';\nimport mapToArray from './_mapToArray';\nimport setToPairs from './_setToPairs';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n setTag = '[object Set]';\n\n/**\n * Creates a `_.toPairs` or `_.toPairsIn` function.\n *\n * @private\n * @param {Function} keysFunc The function to get the keys of a given object.\n * @returns {Function} Returns the new pairs function.\n */\nfunction createToPairs(keysFunc) {\n return function(object) {\n var tag = getTag(object);\n if (tag == mapTag) {\n return mapToArray(object);\n }\n if (tag == setTag) {\n return setToPairs(object);\n }\n return baseToPairs(object, keysFunc(object));\n };\n}\n\nexport default createToPairs;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_createToPairs.js\n// module id = null\n// module chunks = ","import createToPairs from './_createToPairs';\nimport keys from './keys';\n\n/**\n * Creates an array of own enumerable string keyed-value pairs for `object`\n * which can be consumed by `_.fromPairs`. If `object` is a map or set, its\n * entries are returned.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias entries\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the key-value pairs.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.toPairs(new Foo);\n * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)\n */\nvar toPairs = createToPairs(keys);\n\nexport default toPairs;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/toPairs.js\n// module id = null\n// module chunks = ","import isStrictComparable from './_isStrictComparable';\nimport toPairs from './toPairs';\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = toPairs(object),\n length = result.length;\n\n while (length--) {\n result[length][2] = isStrictComparable(result[length][1]);\n }\n return result;\n}\n\nexport default getMatchData;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_getMatchData.js\n// module id = null\n// module chunks = ","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_matchesStrictComparable.js\n// module id = null\n// module chunks = ","import baseIsMatch from './_baseIsMatch';\nimport getMatchData from './_getMatchData';\nimport matchesStrictComparable from './_matchesStrictComparable';\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nexport default baseMatches;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseMatches.js\n// module id = null\n// module chunks = ","import Symbol from './_Symbol';\nimport isSymbol from './isSymbol';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default baseToString;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseToString.js\n// module id = null\n// module chunks = ","import baseToString from './_baseToString';\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nexport default toString;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/toString.js\n// module id = null\n// module chunks = ","import memoize from './memoize';\nimport toString from './toString';\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoize(function(string) {\n var result = [];\n toString(string).replace(rePropName, function(match, number, quote, string) {\n result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nexport default stringToPath;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_stringToPath.js\n// module id = null\n// module chunks = ","import isArray from './isArray';\nimport stringToPath from './_stringToPath';\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value) {\n return isArray(value) ? value : stringToPath(value);\n}\n\nexport default castPath;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_castPath.js\n// module id = null\n// module chunks = ","import isArray from './isArray';\nimport isSymbol from './isSymbol';\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nexport default isKey;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_isKey.js\n// module id = null\n// module chunks = ","import isSymbol from './isSymbol';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default toKey;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_toKey.js\n// module id = null\n// module chunks = ","import castPath from './_castPath';\nimport isKey from './_isKey';\nimport toKey from './_toKey';\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = isKey(path, object) ? [path] : castPath(path);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nexport default baseGet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseGet.js\n// module id = null\n// module chunks = ","import baseGet from './_baseGet';\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is used in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nexport default get;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/get.js\n// module id = null\n// module chunks = ","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return key in Object(object);\n}\n\nexport default baseHasIn;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseHasIn.js\n// module id = null\n// module chunks = ","import castPath from './_castPath';\nimport isArguments from './isArguments';\nimport isArray from './isArray';\nimport isIndex from './_isIndex';\nimport isKey from './_isKey';\nimport isLength from './isLength';\nimport isString from './isString';\nimport toKey from './_toKey';\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = isKey(path, object) ? [path] : castPath(path);\n\n var result,\n index = -1,\n length = path.length;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result) {\n return result;\n }\n var length = object ? object.length : 0;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isString(object) || isArguments(object));\n}\n\nexport default hasPath;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_hasPath.js\n// module id = null\n// module chunks = ","import baseHasIn from './_baseHasIn';\nimport hasPath from './_hasPath';\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nexport default hasIn;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/hasIn.js\n// module id = null\n// module chunks = ","import baseIsEqual from './_baseIsEqual';\nimport get from './get';\nimport hasIn from './hasIn';\nimport isKey from './_isKey';\nimport isStrictComparable from './_isStrictComparable';\nimport matchesStrictComparable from './_matchesStrictComparable';\nimport toKey from './_toKey';\n\n/** Used to compose bitmasks for comparison styles. */\nvar UNORDERED_COMPARE_FLAG = 1,\n PARTIAL_COMPARE_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);\n };\n}\n\nexport default baseMatchesProperty;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseMatchesProperty.js\n// module id = null\n// module chunks = ","/**\n * This method returns the first argument given to it.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'user': 'fred' };\n *\n * _.identity(object) === object;\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/identity.js\n// module id = null\n// module chunks = ","import baseGet from './_baseGet';\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nexport default basePropertyDeep;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_basePropertyDeep.js\n// module id = null\n// module chunks = ","import baseProperty from './_baseProperty';\nimport basePropertyDeep from './_basePropertyDeep';\nimport isKey from './_isKey';\nimport toKey from './_toKey';\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nexport default property;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/property.js\n// module id = null\n// module chunks = ","import baseMatches from './_baseMatches';\nimport baseMatchesProperty from './_baseMatchesProperty';\nimport identity from './identity';\nimport isArray from './isArray';\nimport property from './property';\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nexport default baseIteratee;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseIteratee.js\n// module id = null\n// module chunks = ","import baseDifference from './_baseDifference';\nimport baseFlatten from './_baseFlatten';\nimport baseIteratee from './_baseIteratee';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport last from './last';\nimport rest from './rest';\n\n/**\n * This method is like `_.difference` except that it accepts `iteratee` which\n * is invoked for each element of `array` and `values` to generate the criterion\n * by which they're compared. Result values are chosen from the first array.\n * The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Array|Function|Object|string} [iteratee=_.identity]\n * The iteratee invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);\n * // => [3.1, 1.3]\n *\n * // The `_.property` iteratee shorthand.\n * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');\n * // => [{ 'x': 2 }]\n */\nvar differenceBy = rest(function(array, values) {\n var iteratee = last(values);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), baseIteratee(iteratee))\n : [];\n});\n\nexport default differenceBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/differenceBy.js\n// module id = null\n// module chunks = ","import baseDifference from './_baseDifference';\nimport baseFlatten from './_baseFlatten';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport last from './last';\nimport rest from './rest';\n\n/**\n * This method is like `_.difference` except that it accepts `comparator`\n * which is invoked to compare elements of `array` to `values`. Result values\n * are chosen from the first array. The comparator is invoked with two arguments:\n * (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n *\n * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }]\n */\nvar differenceWith = rest(function(array, values) {\n var comparator = last(values);\n if (isArrayLikeObject(comparator)) {\n comparator = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n : [];\n});\n\nexport default differenceWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/differenceWith.js\n// module id = null\n// module chunks = ","import baseSlice from './_baseSlice';\nimport toInteger from './toInteger';\n\n/**\n * Creates a slice of `array` with `n` elements dropped from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.drop([1, 2, 3]);\n * // => [2, 3]\n *\n * _.drop([1, 2, 3], 2);\n * // => [3]\n *\n * _.drop([1, 2, 3], 5);\n * // => []\n *\n * _.drop([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\nfunction drop(array, n, guard) {\n var length = array ? array.length : 0;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n return baseSlice(array, n < 0 ? 0 : n, length);\n}\n\nexport default drop;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/drop.js\n// module id = null\n// module chunks = ","import baseSlice from './_baseSlice';\nimport toInteger from './toInteger';\n\n/**\n * Creates a slice of `array` with `n` elements dropped from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.dropRight([1, 2, 3]);\n * // => [1, 2]\n *\n * _.dropRight([1, 2, 3], 2);\n * // => [1]\n *\n * _.dropRight([1, 2, 3], 5);\n * // => []\n *\n * _.dropRight([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\nfunction dropRight(array, n, guard) {\n var length = array ? array.length : 0;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n n = length - n;\n return baseSlice(array, 0, n < 0 ? 0 : n);\n}\n\nexport default dropRight;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/dropRight.js\n// module id = null\n// module chunks = ","import baseSlice from './_baseSlice';\n\n/**\n * The base implementation of methods like `_.dropWhile` and `_.takeWhile`\n * without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to query.\n * @param {Function} predicate The function invoked per iteration.\n * @param {boolean} [isDrop] Specify dropping elements instead of taking them.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseWhile(array, predicate, isDrop, fromRight) {\n var length = array.length,\n index = fromRight ? length : -1;\n\n while ((fromRight ? index-- : ++index < length) &&\n predicate(array[index], index, array)) {}\n\n return isDrop\n ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))\n : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));\n}\n\nexport default baseWhile;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseWhile.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport baseWhile from './_baseWhile';\n\n/**\n * Creates a slice of `array` excluding elements dropped from the end.\n * Elements are dropped until `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Array|Function|Object|string} [predicate=_.identity]\n * The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.dropRightWhile(users, function(o) { return !o.active; });\n * // => objects for ['barney']\n *\n * // The `_.matches` iteratee shorthand.\n * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });\n * // => objects for ['barney', 'fred']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.dropRightWhile(users, ['active', false]);\n * // => objects for ['barney']\n *\n * // The `_.property` iteratee shorthand.\n * _.dropRightWhile(users, 'active');\n * // => objects for ['barney', 'fred', 'pebbles']\n */\nfunction dropRightWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, baseIteratee(predicate, 3), true, true)\n : [];\n}\n\nexport default dropRightWhile;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/dropRightWhile.js\n// module id = null\n// module chunks = ","import baseClamp from './_baseClamp';\nimport toInteger from './toInteger';\n\n/** Used as references for the maximum length and index of an array. */\nvar MAX_ARRAY_LENGTH = 4294967295;\n\n/**\n * Converts `value` to an integer suitable for use as the length of an\n * array-like object.\n *\n * **Note:** This method is based on\n * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toLength(3.2);\n * // => 3\n *\n * _.toLength(Number.MIN_VALUE);\n * // => 0\n *\n * _.toLength(Infinity);\n * // => 4294967295\n *\n * _.toLength('3.2');\n * // => 3\n */\nfunction toLength(value) {\n return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;\n}\n\nexport default toLength;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/toLength.js\n// module id = null\n// module chunks = ","/**\n * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.\n *\n * @private\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n */\nfunction baseClamp(number, lower, upper) {\n if (number === number) {\n if (upper !== undefined) {\n number = number <= upper ? number : upper;\n }\n if (lower !== undefined) {\n number = number >= lower ? number : lower;\n }\n }\n return number;\n}\n\nexport default baseClamp;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseClamp.js\n// module id = null\n// module chunks = ","import toInteger from './toInteger';\nimport toLength from './toLength';\n\n/**\n * The base implementation of `_.fill` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to fill.\n * @param {*} value The value to fill `array` with.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns `array`.\n */\nfunction baseFill(array, value, start, end) {\n var length = array.length;\n\n start = toInteger(start);\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = (end === undefined || end > length) ? length : toInteger(end);\n if (end < 0) {\n end += length;\n }\n end = start > end ? 0 : toLength(end);\n while (start < end) {\n array[start++] = value;\n }\n return array;\n}\n\nexport default baseFill;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseFill.js\n// module id = null\n// module chunks = ","import baseFill from './_baseFill';\nimport isIterateeCall from './_isIterateeCall';\n\n/**\n * Fills elements of `array` with `value` from `start` up to, but not\n * including, `end`.\n *\n * **Note:** This method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 3.2.0\n * @category Array\n * @param {Array} array The array to fill.\n * @param {*} value The value to fill `array` with.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _.fill(array, 'a');\n * console.log(array);\n * // => ['a', 'a', 'a']\n *\n * _.fill(Array(3), 2);\n * // => [2, 2, 2]\n *\n * _.fill([4, 6, 8, 10], '*', 1, 3);\n * // => [4, '*', '*', 10]\n */\nfunction fill(array, value, start, end) {\n var length = array ? array.length : 0;\n if (!length) {\n return [];\n }\n if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {\n start = 0;\n end = length;\n }\n return baseFill(array, value, start, end);\n}\n\nexport default fill;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/fill.js\n// module id = null\n// module chunks = ","import baseFindIndex from './_baseFindIndex';\nimport baseIteratee from './_baseIteratee';\n\n/**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to search.\n * @param {Array|Function|Object|string} [predicate=_.identity]\n * The function invoked per iteration.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\nfunction findIndex(array, predicate) {\n return (array && array.length)\n ? baseFindIndex(array, baseIteratee(predicate, 3))\n : -1;\n}\n\nexport default findIndex;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/findIndex.js\n// module id = null\n// module chunks = ","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to search.\n * @param {Function} predicate The function invoked per iteration.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromRight) {\n var length = array.length,\n index = fromRight ? length : -1;\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseFindIndex;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseFindIndex.js\n// module id = null\n// module chunks = ","import baseFlatten from './_baseFlatten';\n\n/**\n * Flattens `array` a single level deep.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flatten([1, [2, [3, [4]], 5]]);\n * // => [1, 2, [3, [4]], 5]\n */\nfunction flatten(array) {\n var length = array ? array.length : 0;\n return length ? baseFlatten(array, 1) : [];\n}\n\nexport default flatten;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/flatten.js\n// module id = null\n// module chunks = ","/**\n * Gets the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias first\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the first element of `array`.\n * @example\n *\n * _.head([1, 2, 3]);\n * // => 1\n *\n * _.head([]);\n * // => undefined\n */\nfunction head(array) {\n return (array && array.length) ? array[0] : undefined;\n}\n\nexport default head;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/head.js\n// module id = null\n// module chunks = ","import isArrayLikeObject from './isArrayLikeObject';\n\n/**\n * Casts `value` to an empty array if it's not an array like object.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Array|Object} Returns the cast array-like object.\n */\nfunction castArrayLikeObject(value) {\n return isArrayLikeObject(value) ? value : [];\n}\n\nexport default castArrayLikeObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_castArrayLikeObject.js\n// module id = null\n// module chunks = ","import SetCache from './_SetCache';\nimport arrayIncludes from './_arrayIncludes';\nimport arrayIncludesWith from './_arrayIncludesWith';\nimport arrayMap from './_arrayMap';\nimport baseUnary from './_baseUnary';\nimport cacheHas from './_cacheHas';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMin = Math.min;\n\n/**\n * The base implementation of methods like `_.intersection`, without support\n * for iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of shared values.\n */\nfunction baseIntersection(arrays, iteratee, comparator) {\n var includes = comparator ? arrayIncludesWith : arrayIncludes,\n length = arrays[0].length,\n othLength = arrays.length,\n othIndex = othLength,\n caches = Array(othLength),\n maxLength = Infinity,\n result = [];\n\n while (othIndex--) {\n var array = arrays[othIndex];\n if (othIndex && iteratee) {\n array = arrayMap(array, baseUnary(iteratee));\n }\n maxLength = nativeMin(array.length, maxLength);\n caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n ? new SetCache(othIndex && array)\n : undefined;\n }\n array = arrays[0];\n\n var index = -1,\n seen = caches[0];\n\n outer:\n while (++index < length && result.length < maxLength) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (!(seen\n ? cacheHas(seen, computed)\n : includes(result, computed, comparator)\n )) {\n othIndex = othLength;\n while (--othIndex) {\n var cache = caches[othIndex];\n if (!(cache\n ? cacheHas(cache, computed)\n : includes(arrays[othIndex], computed, comparator))\n ) {\n continue outer;\n }\n }\n if (seen) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n}\n\nexport default baseIntersection;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseIntersection.js\n// module id = null\n// module chunks = ","import arrayMap from './_arrayMap';\nimport baseIntersection from './_baseIntersection';\nimport castArrayLikeObject from './_castArrayLikeObject';\nimport rest from './rest';\n\n/**\n * Creates an array of unique values that are included in all given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons. The order of result values is determined by the\n * order they occur in the first array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersection([2, 1], [4, 2], [1, 2]);\n * // => [2]\n */\nvar intersection = rest(function(arrays) {\n var mapped = arrayMap(arrays, castArrayLikeObject);\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped)\n : [];\n});\n\nexport default intersection;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/intersection.js\n// module id = null\n// module chunks = ","import arrayMap from './_arrayMap';\nimport baseIntersection from './_baseIntersection';\nimport baseIteratee from './_baseIteratee';\nimport castArrayLikeObject from './_castArrayLikeObject';\nimport last from './last';\nimport rest from './rest';\n\n/**\n * This method is like `_.intersection` except that it accepts `iteratee`\n * which is invoked for each element of each `arrays` to generate the criterion\n * by which they're compared. Result values are chosen from the first array.\n * The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Array|Function|Object|string} [iteratee=_.identity]\n * The iteratee invoked per element.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);\n * // => [2.1]\n *\n * // The `_.property` iteratee shorthand.\n * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }]\n */\nvar intersectionBy = rest(function(arrays) {\n var iteratee = last(arrays),\n mapped = arrayMap(arrays, castArrayLikeObject);\n\n if (iteratee === last(mapped)) {\n iteratee = undefined;\n } else {\n mapped.pop();\n }\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped, baseIteratee(iteratee))\n : [];\n});\n\nexport default intersectionBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/intersectionBy.js\n// module id = null\n// module chunks = ","import arrayMap from './_arrayMap';\nimport baseIntersection from './_baseIntersection';\nimport castArrayLikeObject from './_castArrayLikeObject';\nimport last from './last';\nimport rest from './rest';\n\n/**\n * This method is like `_.intersection` except that it accepts `comparator`\n * which is invoked to compare elements of `arrays`. Result values are chosen\n * from the first array. The comparator is invoked with two arguments:\n * (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.intersectionWith(objects, others, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }]\n */\nvar intersectionWith = rest(function(arrays) {\n var comparator = last(arrays),\n mapped = arrayMap(arrays, castArrayLikeObject);\n\n if (comparator === last(mapped)) {\n comparator = undefined;\n } else {\n mapped.pop();\n }\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped, undefined, comparator)\n : [];\n});\n\nexport default intersectionWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/intersectionWith.js\n// module id = null\n// module chunks = ","/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeJoin = arrayProto.join;\n\n/**\n * Converts all elements in `array` into a string separated by `separator`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to convert.\n * @param {string} [separator=','] The element separator.\n * @returns {string} Returns the joined string.\n * @example\n *\n * _.join(['a', 'b', 'c'], '~');\n * // => 'a~b~c'\n */\nfunction join(array, separator) {\n return array ? nativeJoin.call(array, separator) : '';\n}\n\nexport default join;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/join.js\n// module id = null\n// module chunks = ","import baseNth from './_baseNth';\nimport toInteger from './toInteger';\n\n/**\n * Gets the element at `n` index of `array`. If `n` is negative, the nth\n * element from the end is returned.\n *\n * @static\n * @memberOf _\n * @since 4.11.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=0] The index of the element to return.\n * @returns {*} Returns the nth element of `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'd'];\n *\n * _.nth(array, 1);\n * // => 'b'\n *\n * _.nth(array, -2);\n * // => 'c';\n */\nfunction nth(array, n) {\n return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;\n}\n\nexport default nth;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/nth.js\n// module id = null\n// module chunks = ","import isIndex from './_isIndex';\n\n/**\n * The base implementation of `_.nth` which doesn't coerce `n` to an integer.\n *\n * @private\n * @param {Array} array The array to query.\n * @param {number} n The index of the element to return.\n * @returns {*} Returns the nth element of `array`.\n */\nfunction baseNth(array, n) {\n var length = array.length;\n if (!length) {\n return;\n }\n n += n < 0 ? length : 0;\n return isIndex(n, length) ? array[n] : undefined;\n}\n\nexport default baseNth;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseNth.js\n// module id = null\n// module chunks = ","import arrayMap from './_arrayMap';\nimport baseIndexOf from './_baseIndexOf';\nimport baseIndexOfWith from './_baseIndexOfWith';\nimport baseUnary from './_baseUnary';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * The base implementation of `_.pullAllBy` without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns `array`.\n */\nfunction basePullAll(array, values, iteratee, comparator) {\n var indexOf = comparator ? baseIndexOfWith : baseIndexOf,\n index = -1,\n length = values.length,\n seen = array;\n\n if (iteratee) {\n seen = arrayMap(array, baseUnary(iteratee));\n }\n while (++index < length) {\n var fromIndex = 0,\n value = values[index],\n computed = iteratee ? iteratee(value) : value;\n\n while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {\n if (seen !== array) {\n splice.call(seen, fromIndex, 1);\n }\n splice.call(array, fromIndex, 1);\n }\n }\n return array;\n}\n\nexport default basePullAll;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_basePullAll.js\n// module id = null\n// module chunks = ","/**\n * This function is like `baseIndexOf` except that it accepts a comparator.\n *\n * @private\n * @param {Array} array The array to search.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseIndexOfWith(array, value, fromIndex, comparator) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (comparator(array[index], value)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseIndexOfWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseIndexOfWith.js\n// module id = null\n// module chunks = ","import basePullAll from './_basePullAll';\n\n/**\n * This method is like `_.pull` except that it accepts an array of values to remove.\n *\n * **Note:** Unlike `_.difference`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3, 1, 2, 3];\n *\n * _.pullAll(array, [2, 3]);\n * console.log(array);\n * // => [1, 1]\n */\nfunction pullAll(array, values) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values)\n : array;\n}\n\nexport default pullAll;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/pullAll.js\n// module id = null\n// module chunks = ","import pullAll from './pullAll';\nimport rest from './rest';\n\n/**\n * Removes all given values from `array` using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`\n * to remove elements from an array by predicate.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {...*} [values] The values to remove.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3, 1, 2, 3];\n *\n * _.pull(array, 2, 3);\n * console.log(array);\n * // => [1, 1]\n */\nvar pull = rest(pullAll);\n\nexport default pull;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/pull.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport basePullAll from './_basePullAll';\n\n/**\n * This method is like `_.pullAll` except that it accepts `iteratee` which is\n * invoked for each element of `array` and `values` to generate the criterion\n * by which they're compared. The iteratee is invoked with one argument: (value).\n *\n * **Note:** Unlike `_.differenceBy`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Array|Function|Object|string} [iteratee=_.identity]\n * The iteratee invoked per element.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];\n *\n * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');\n * console.log(array);\n * // => [{ 'x': 2 }]\n */\nfunction pullAllBy(array, values, iteratee) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values, baseIteratee(iteratee))\n : array;\n}\n\nexport default pullAllBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/pullAllBy.js\n// module id = null\n// module chunks = ","import baseGet from './_baseGet';\nimport baseSlice from './_baseSlice';\n\n/**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\nfunction parent(object, path) {\n return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));\n}\n\nexport default parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_parent.js\n// module id = null\n// module chunks = ","import get from './get';\n\n/**\n * The base implementation of `_.at` without support for individual paths.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {string[]} paths The property paths of elements to pick.\n * @returns {Array} Returns the picked elements.\n */\nfunction baseAt(object, paths) {\n var index = -1,\n isNil = object == null,\n length = paths.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = isNil ? undefined : get(object, paths[index]);\n }\n return result;\n}\n\nexport default baseAt;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseAt.js\n// module id = null\n// module chunks = ","import castPath from './_castPath';\nimport isIndex from './_isIndex';\nimport isKey from './_isKey';\nimport last from './last';\nimport parent from './_parent';\nimport toKey from './_toKey';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * The base implementation of `_.pullAt` without support for individual\n * indexes or capturing the removed elements.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {number[]} indexes The indexes of elements to remove.\n * @returns {Array} Returns `array`.\n */\nfunction basePullAt(array, indexes) {\n var length = array ? indexes.length : 0,\n lastIndex = length - 1;\n\n while (length--) {\n var index = indexes[length];\n if (length == lastIndex || index !== previous) {\n var previous = index;\n if (isIndex(index)) {\n splice.call(array, index, 1);\n }\n else if (!isKey(index, array)) {\n var path = castPath(index),\n object = parent(array, path);\n\n if (object != null) {\n delete object[toKey(last(path))];\n }\n }\n else {\n delete array[toKey(index)];\n }\n }\n }\n return array;\n}\n\nexport default basePullAt;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_basePullAt.js\n// module id = null\n// module chunks = ","import isSymbol from './isSymbol';\n\n/**\n * Compares values to sort them in ascending order.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {number} Returns the sort order indicator for `value`.\n */\nfunction compareAscending(value, other) {\n if (value !== other) {\n var valIsDefined = value !== undefined,\n valIsNull = value === null,\n valIsReflexive = value === value,\n valIsSymbol = isSymbol(value);\n\n var othIsDefined = other !== undefined,\n othIsNull = other === null,\n othIsReflexive = other === other,\n othIsSymbol = isSymbol(other);\n\n if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n (valIsNull && othIsDefined && othIsReflexive) ||\n (!valIsDefined && othIsReflexive) ||\n !valIsReflexive) {\n return 1;\n }\n if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n (othIsNull && valIsDefined && valIsReflexive) ||\n (!othIsDefined && valIsReflexive) ||\n !othIsReflexive) {\n return -1;\n }\n }\n return 0;\n}\n\nexport default compareAscending;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_compareAscending.js\n// module id = null\n// module chunks = ","import arrayMap from './_arrayMap';\nimport baseAt from './_baseAt';\nimport baseFlatten from './_baseFlatten';\nimport basePullAt from './_basePullAt';\nimport compareAscending from './_compareAscending';\nimport isIndex from './_isIndex';\nimport rest from './rest';\n\n/**\n * Removes elements from `array` corresponding to `indexes` and returns an\n * array of removed elements.\n *\n * **Note:** Unlike `_.at`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {...(number|number[])} [indexes] The indexes of elements to remove.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = [5, 10, 15, 20];\n * var evens = _.pullAt(array, 1, 3);\n *\n * console.log(array);\n * // => [5, 15]\n *\n * console.log(evens);\n * // => [10, 20]\n */\nvar pullAt = rest(function(array, indexes) {\n indexes = baseFlatten(indexes, 1);\n\n var length = array ? array.length : 0,\n result = baseAt(array, indexes);\n\n basePullAt(array, arrayMap(indexes, function(index) {\n return isIndex(index, length) ? +index : index;\n }).sort(compareAscending));\n\n return result;\n});\n\nexport default pullAt;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/pullAt.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport basePullAt from './_basePullAt';\n\n/**\n * Removes all elements from `array` that `predicate` returns truthy for\n * and returns an array of the removed elements. The predicate is invoked\n * with three arguments: (value, index, array).\n *\n * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n * to pull elements from an array by value.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array|Function|Object|string} [predicate=_.identity]\n * The function invoked per iteration.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = [1, 2, 3, 4];\n * var evens = _.remove(array, function(n) {\n * return n % 2 == 0;\n * });\n *\n * console.log(array);\n * // => [1, 3]\n *\n * console.log(evens);\n * // => [2, 4]\n */\nfunction remove(array, predicate) {\n var result = [];\n if (!(array && array.length)) {\n return result;\n }\n var index = -1,\n indexes = [],\n length = array.length;\n\n predicate = baseIteratee(predicate, 3);\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result.push(value);\n indexes.push(index);\n }\n }\n basePullAt(array, indexes);\n return result;\n}\n\nexport default remove;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/remove.js\n// module id = null\n// module chunks = ","/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeReverse = arrayProto.reverse;\n\n/**\n * Reverses `array` so that the first element becomes the last, the second\n * element becomes the second to last, and so on.\n *\n * **Note:** This method mutates `array` and is based on\n * [`Array#reverse`](https://mdn.io/Array/reverse).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _.reverse(array);\n * // => [3, 2, 1]\n *\n * console.log(array);\n * // => [3, 2, 1]\n */\nfunction reverse(array) {\n return array ? nativeReverse.call(array) : array;\n}\n\nexport default reverse;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/reverse.js\n// module id = null\n// module chunks = ","import baseSortedIndexBy from './_baseSortedIndexBy';\nimport identity from './identity';\nimport isSymbol from './isSymbol';\n\n/** Used as references for the maximum length and index of an array. */\nvar MAX_ARRAY_LENGTH = 4294967295,\n HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\n\n/**\n * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which\n * performs a binary search of `array` to determine the index at which `value`\n * should be inserted into `array` in order to maintain its sort order.\n *\n * @private\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {boolean} [retHighest] Specify returning the highest qualified index.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n */\nfunction baseSortedIndex(array, value, retHighest) {\n var low = 0,\n high = array ? array.length : low;\n\n if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\n while (low < high) {\n var mid = (low + high) >>> 1,\n computed = array[mid];\n\n if (computed !== null && !isSymbol(computed) &&\n (retHighest ? (computed <= value) : (computed < value))) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return high;\n }\n return baseSortedIndexBy(array, value, identity, retHighest);\n}\n\nexport default baseSortedIndex;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseSortedIndex.js\n// module id = null\n// module chunks = ","import isSymbol from './isSymbol';\n\n/** Used as references for the maximum length and index of an array. */\nvar MAX_ARRAY_LENGTH = 4294967295,\n MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeFloor = Math.floor,\n nativeMin = Math.min;\n\n/**\n * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`\n * which invokes `iteratee` for `value` and each element of `array` to compute\n * their sort ranking. The iteratee is invoked with one argument; (value).\n *\n * @private\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} iteratee The iteratee invoked per element.\n * @param {boolean} [retHighest] Specify returning the highest qualified index.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n */\nfunction baseSortedIndexBy(array, value, iteratee, retHighest) {\n value = iteratee(value);\n\n var low = 0,\n high = array ? array.length : 0,\n valIsNaN = value !== value,\n valIsNull = value === null,\n valIsSymbol = isSymbol(value),\n valIsUndefined = value === undefined;\n\n while (low < high) {\n var mid = nativeFloor((low + high) / 2),\n computed = iteratee(array[mid]),\n othIsDefined = computed !== undefined,\n othIsNull = computed === null,\n othIsReflexive = computed === computed,\n othIsSymbol = isSymbol(computed);\n\n if (valIsNaN) {\n var setLow = retHighest || othIsReflexive;\n } else if (valIsUndefined) {\n setLow = othIsReflexive && (retHighest || othIsDefined);\n } else if (valIsNull) {\n setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);\n } else if (valIsSymbol) {\n setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);\n } else if (othIsNull || othIsSymbol) {\n setLow = false;\n } else {\n setLow = retHighest ? (computed <= value) : (computed < value);\n }\n if (setLow) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return nativeMin(high, MAX_ARRAY_INDEX);\n}\n\nexport default baseSortedIndexBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseSortedIndexBy.js\n// module id = null\n// module chunks = ","import baseSortedIndex from './_baseSortedIndex';\n\n/**\n * Uses a binary search to determine the lowest index at which `value`\n * should be inserted into `array` in order to maintain its sort order.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * _.sortedIndex([30, 50], 40);\n * // => 1\n *\n * _.sortedIndex([4, 5], 4);\n * // => 0\n */\nfunction sortedIndex(array, value) {\n return baseSortedIndex(array, value);\n}\n\nexport default sortedIndex;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/sortedIndex.js\n// module id = null\n// module chunks = ","import baseSortedUniq from './_baseSortedUniq';\n\n/**\n * This method is like `_.uniq` except that it's designed and optimized\n * for sorted arrays.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.sortedUniq([1, 1, 2]);\n * // => [1, 2]\n */\nfunction sortedUniq(array) {\n return (array && array.length)\n ? baseSortedUniq(array)\n : [];\n}\n\nexport default sortedUniq;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/sortedUniq.js\n// module id = null\n// module chunks = ","import eq from './eq';\n\n/**\n * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\nfunction baseSortedUniq(array, iteratee) {\n var index = -1,\n length = array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n if (!index || !eq(computed, seen)) {\n var seen = computed;\n result[resIndex++] = value === 0 ? 0 : value;\n }\n }\n return result;\n}\n\nexport default baseSortedUniq;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseSortedUniq.js\n// module id = null\n// module chunks = ","import Set from './_Set';\nimport noop from './noop';\nimport setToArray from './_setToArray';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Creates a set of `values`.\n *\n * @private\n * @param {Array} values The values to add to the set.\n * @returns {Object} Returns the new set.\n */\nvar createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n return new Set(values);\n};\n\nexport default createSet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_createSet.js\n// module id = null\n// module chunks = ","import SetCache from './_SetCache';\nimport arrayIncludes from './_arrayIncludes';\nimport arrayIncludesWith from './_arrayIncludesWith';\nimport cacheHas from './_cacheHas';\nimport createSet from './_createSet';\nimport setToArray from './_setToArray';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\nfunction baseUniq(array, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n length = array.length,\n isCommon = true,\n result = [],\n seen = result;\n\n if (comparator) {\n isCommon = false;\n includes = arrayIncludesWith;\n }\n else if (length >= LARGE_ARRAY_SIZE) {\n var set = iteratee ? null : createSet(array);\n if (set) {\n return setToArray(set);\n }\n isCommon = false;\n includes = cacheHas;\n seen = new SetCache;\n }\n else {\n seen = iteratee ? [] : result;\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var seenIndex = seen.length;\n while (seenIndex--) {\n if (seen[seenIndex] === computed) {\n continue outer;\n }\n }\n if (iteratee) {\n seen.push(computed);\n }\n result.push(value);\n }\n else if (!includes(seen, computed, comparator)) {\n if (seen !== result) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n}\n\nexport default baseUniq;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseUniq.js\n// module id = null\n// module chunks = ","/**\n * A no-operation function that returns `undefined` regardless of the\n * arguments it receives.\n *\n * @static\n * @memberOf _\n * @since 2.3.0\n * @category Util\n * @example\n *\n * var object = { 'user': 'fred' };\n *\n * _.noop(object) === undefined;\n * // => true\n */\nfunction noop() {\n // No operation performed.\n}\n\nexport default noop;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/noop.js\n// module id = null\n// module chunks = ","import baseFlatten from './_baseFlatten';\nimport baseUniq from './_baseUniq';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport rest from './rest';\n\n/**\n * Creates an array of unique values, in order, from all given arrays using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.union([2, 1], [4, 2], [1, 2]);\n * // => [2, 1, 4]\n */\nvar union = rest(function(arrays) {\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));\n});\n\nexport default union;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/union.js\n// module id = null\n// module chunks = ","import baseFlatten from './_baseFlatten';\nimport baseIteratee from './_baseIteratee';\nimport baseUniq from './_baseUniq';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport last from './last';\nimport rest from './rest';\n\n/**\n * This method is like `_.union` except that it accepts `iteratee` which is\n * invoked for each element of each `arrays` to generate the criterion by\n * which uniqueness is computed. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Array|Function|Object|string} [iteratee=_.identity]\n * The iteratee invoked per element.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);\n * // => [2.1, 1.2, 4.3]\n *\n * // The `_.property` iteratee shorthand.\n * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\nvar unionBy = rest(function(arrays) {\n var iteratee = last(arrays);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), baseIteratee(iteratee));\n});\n\nexport default unionBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/unionBy.js\n// module id = null\n// module chunks = ","import baseFlatten from './_baseFlatten';\nimport baseUniq from './_baseUniq';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport last from './last';\nimport rest from './rest';\n\n/**\n * This method is like `_.union` except that it accepts `comparator` which\n * is invoked to compare elements of `arrays`. The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.unionWith(objects, others, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n */\nvar unionWith = rest(function(arrays) {\n var comparator = last(arrays);\n if (isArrayLikeObject(comparator)) {\n comparator = undefined;\n }\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);\n});\n\nexport default unionWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/unionWith.js\n// module id = null\n// module chunks = ","import baseUniq from './_baseUniq';\n\n/**\n * Creates a duplicate-free version of an array, using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons, in which only the first occurrence of each\n * element is kept.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniq([2, 1, 2]);\n * // => [2, 1]\n */\nfunction uniq(array) {\n return (array && array.length)\n ? baseUniq(array)\n : [];\n}\n\nexport default uniq;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/uniq.js\n// module id = null\n// module chunks = ","import arrayFilter from './_arrayFilter';\nimport arrayMap from './_arrayMap';\nimport baseProperty from './_baseProperty';\nimport baseTimes from './_baseTimes';\nimport isArrayLikeObject from './isArrayLikeObject';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This method is like `_.zip` except that it accepts an array of grouped\n * elements and creates an array regrouping the elements to their pre-zip\n * configuration.\n *\n * @static\n * @memberOf _\n * @since 1.2.0\n * @category Array\n * @param {Array} array The array of grouped elements to process.\n * @returns {Array} Returns the new array of regrouped elements.\n * @example\n *\n * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);\n * // => [['fred', 30, true], ['barney', 40, false]]\n *\n * _.unzip(zipped);\n * // => [['fred', 'barney'], [30, 40], [true, false]]\n */\nfunction unzip(array) {\n if (!(array && array.length)) {\n return [];\n }\n var length = 0;\n array = arrayFilter(array, function(group) {\n if (isArrayLikeObject(group)) {\n length = nativeMax(group.length, length);\n return true;\n }\n });\n return baseTimes(length, function(index) {\n return arrayMap(array, baseProperty(index));\n });\n}\n\nexport default unzip;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/unzip.js\n// module id = null\n// module chunks = ","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_arrayFilter.js\n// module id = null\n// module chunks = ","import apply from './_apply';\nimport arrayMap from './_arrayMap';\nimport unzip from './unzip';\n\n/**\n * This method is like `_.unzip` except that it accepts `iteratee` to specify\n * how regrouped values should be combined. The iteratee is invoked with the\n * elements of each group: (...group).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Array\n * @param {Array} array The array of grouped elements to process.\n * @param {Function} [iteratee=_.identity] The function to combine\n * regrouped values.\n * @returns {Array} Returns the new array of regrouped elements.\n * @example\n *\n * var zipped = _.zip([1, 2], [10, 20], [100, 200]);\n * // => [[1, 10, 100], [2, 20, 200]]\n *\n * _.unzipWith(zipped, _.add);\n * // => [3, 30, 300]\n */\nfunction unzipWith(array, iteratee) {\n if (!(array && array.length)) {\n return [];\n }\n var result = unzip(array);\n if (iteratee == null) {\n return result;\n }\n return arrayMap(result, function(group) {\n return apply(iteratee, undefined, group);\n });\n}\n\nexport default unzipWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/unzipWith.js\n// module id = null\n// module chunks = ","import baseDifference from './_baseDifference';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport rest from './rest';\n\n/**\n * Creates an array excluding all given values using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...*} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.xor\n * @example\n *\n * _.without([1, 2, 1, 3], 1, 2);\n * // => [3]\n */\nvar without = rest(function(array, values) {\n return isArrayLikeObject(array)\n ? baseDifference(array, values)\n : [];\n});\n\nexport default without;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/without.js\n// module id = null\n// module chunks = ","import arrayPush from './_arrayPush';\nimport baseDifference from './_baseDifference';\nimport baseUniq from './_baseUniq';\n\n/**\n * The base implementation of methods like `_.xor`, without support for\n * iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of values.\n */\nfunction baseXor(arrays, iteratee, comparator) {\n var index = -1,\n length = arrays.length;\n\n while (++index < length) {\n var result = result\n ? arrayPush(\n baseDifference(result, arrays[index], iteratee, comparator),\n baseDifference(arrays[index], result, iteratee, comparator)\n )\n : arrays[index];\n }\n return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];\n}\n\nexport default baseXor;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseXor.js\n// module id = null\n// module chunks = ","import arrayFilter from './_arrayFilter';\nimport baseXor from './_baseXor';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport rest from './rest';\n\n/**\n * Creates an array of unique values that is the\n * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)\n * of the given arrays. The order of result values is determined by the order\n * they occur in the arrays.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.without\n * @example\n *\n * _.xor([2, 1], [4, 2]);\n * // => [1, 4]\n */\nvar xor = rest(function(arrays) {\n return baseXor(arrayFilter(arrays, isArrayLikeObject));\n});\n\nexport default xor;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/xor.js\n// module id = null\n// module chunks = ","import arrayFilter from './_arrayFilter';\nimport baseIteratee from './_baseIteratee';\nimport baseXor from './_baseXor';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport last from './last';\nimport rest from './rest';\n\n/**\n * This method is like `_.xor` except that it accepts `iteratee` which is\n * invoked for each element of each `arrays` to generate the criterion by\n * which by which they're compared. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Array|Function|Object|string} [iteratee=_.identity]\n * The iteratee invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);\n * // => [1.2, 4.3]\n *\n * // The `_.property` iteratee shorthand.\n * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 2 }]\n */\nvar xorBy = rest(function(arrays) {\n var iteratee = last(arrays);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return baseXor(arrayFilter(arrays, isArrayLikeObject), baseIteratee(iteratee));\n});\n\nexport default xorBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/xorBy.js\n// module id = null\n// module chunks = ","import arrayFilter from './_arrayFilter';\nimport baseXor from './_baseXor';\nimport isArrayLikeObject from './isArrayLikeObject';\nimport last from './last';\nimport rest from './rest';\n\n/**\n * This method is like `_.xor` except that it accepts `comparator` which is\n * invoked to compare elements of `arrays`. The comparator is invoked with\n * two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.xorWith(objects, others, _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n */\nvar xorWith = rest(function(arrays) {\n var comparator = last(arrays);\n if (isArrayLikeObject(comparator)) {\n comparator = undefined;\n }\n return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);\n});\n\nexport default xorWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/xorWith.js\n// module id = null\n// module chunks = ","import rest from './rest';\nimport unzip from './unzip';\n\n/**\n * Creates an array of grouped elements, the first of which contains the\n * first elements of the given arrays, the second of which contains the\n * second elements of the given arrays, and so on.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to process.\n * @returns {Array} Returns the new array of grouped elements.\n * @example\n *\n * _.zip(['fred', 'barney'], [30, 40], [true, false]);\n * // => [['fred', 30, true], ['barney', 40, false]]\n */\nvar zip = rest(unzip);\n\nexport default zip;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/zip.js\n// module id = null\n// module chunks = ","/**\n * This base implementation of `_.zipObject` which assigns values using `assignFunc`.\n *\n * @private\n * @param {Array} props The property identifiers.\n * @param {Array} values The property values.\n * @param {Function} assignFunc The function to assign values.\n * @returns {Object} Returns the new object.\n */\nfunction baseZipObject(props, values, assignFunc) {\n var index = -1,\n length = props.length,\n valsLength = values.length,\n result = {};\n\n while (++index < length) {\n var value = index < valsLength ? values[index] : undefined;\n assignFunc(result, props[index], value);\n }\n return result;\n}\n\nexport default baseZipObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseZipObject.js\n// module id = null\n// module chunks = ","import assignValue from './_assignValue';\nimport baseZipObject from './_baseZipObject';\n\n/**\n * This method is like `_.fromPairs` except that it accepts two arrays,\n * one of property identifiers and one of corresponding values.\n *\n * @static\n * @memberOf _\n * @since 0.4.0\n * @category Array\n * @param {Array} [props=[]] The property identifiers.\n * @param {Array} [values=[]] The property values.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.zipObject(['a', 'b'], [1, 2]);\n * // => { 'a': 1, 'b': 2 }\n */\nfunction zipObject(props, values) {\n return baseZipObject(props || [], values || [], assignValue);\n}\n\nexport default zipObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/zipObject.js\n// module id = null\n// module chunks = ","import baseSet from './_baseSet';\nimport baseZipObject from './_baseZipObject';\n\n/**\n * This method is like `_.zipObject` except that it supports property paths.\n *\n * @static\n * @memberOf _\n * @since 4.1.0\n * @category Array\n * @param {Array} [props=[]] The property identifiers.\n * @param {Array} [values=[]] The property values.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);\n * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }\n */\nfunction zipObjectDeep(props, values) {\n return baseZipObject(props || [], values || [], baseSet);\n}\n\nexport default zipObjectDeep;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/zipObjectDeep.js\n// module id = null\n// module chunks = ","import assignValue from './_assignValue';\nimport castPath from './_castPath';\nimport isIndex from './_isIndex';\nimport isKey from './_isKey';\nimport isObject from './isObject';\nimport toKey from './_toKey';\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n path = isKey(path, object) ? [path] : castPath(path);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]);\n if (isObject(nested)) {\n var newValue = value;\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = objValue == null\n ? (isIndex(path[index + 1]) ? [] : {})\n : objValue;\n }\n }\n assignValue(nested, key, newValue);\n }\n nested = nested[key];\n }\n return object;\n}\n\nexport default baseSet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_baseSet.js\n// module id = null\n// module chunks = ","import rest from './rest';\nimport unzipWith from './unzipWith';\n\n/**\n * This method is like `_.zip` except that it accepts `iteratee` to specify\n * how grouped values should be combined. The iteratee is invoked with the\n * elements of each group: (...group).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Array\n * @param {...Array} [arrays] The arrays to process.\n * @param {Function} [iteratee=_.identity] The function to combine grouped values.\n * @returns {Array} Returns the new array of grouped elements.\n * @example\n *\n * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {\n * return a + b + c;\n * });\n * // => [111, 222]\n */\nvar zipWith = rest(function(arrays) {\n var length = arrays.length,\n iteratee = length > 1 ? arrays[length - 1] : undefined;\n\n iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;\n return unzipWith(arrays, iteratee);\n});\n\nexport default zipWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/zipWith.js\n// module id = null\n// module chunks = ","import chunk from './chunk';\nimport compact from './compact';\nimport concat from './concat';\nimport difference from './difference';\nimport differenceBy from './differenceBy';\nimport differenceWith from './differenceWith';\nimport drop from './drop';\nimport dropRight from './dropRight';\nimport dropRightWhile from './dropRightWhile';\nimport dropWhile from './dropWhile';\nimport fill from './fill';\nimport findIndex from './findIndex';\nimport findLastIndex from './findLastIndex';\nimport first from './first';\nimport flatten from './flatten';\nimport flattenDeep from './flattenDeep';\nimport flattenDepth from './flattenDepth';\nimport fromPairs from './fromPairs';\nimport head from './head';\nimport indexOf from './indexOf';\nimport initial from './initial';\nimport intersection from './intersection';\nimport intersectionBy from './intersectionBy';\nimport intersectionWith from './intersectionWith';\nimport join from './join';\nimport last from './last';\nimport lastIndexOf from './lastIndexOf';\nimport nth from './nth';\nimport pull from './pull';\nimport pullAll from './pullAll';\nimport pullAllBy from './pullAllBy';\nimport pullAllWith from './pullAllWith';\nimport pullAt from './pullAt';\nimport remove from './remove';\nimport reverse from './reverse';\nimport slice from './slice';\nimport sortedIndex from './sortedIndex';\nimport sortedIndexBy from './sortedIndexBy';\nimport sortedIndexOf from './sortedIndexOf';\nimport sortedLastIndex from './sortedLastIndex';\nimport sortedLastIndexBy from './sortedLastIndexBy';\nimport sortedLastIndexOf from './sortedLastIndexOf';\nimport sortedUniq from './sortedUniq';\nimport sortedUniqBy from './sortedUniqBy';\nimport tail from './tail';\nimport take from './take';\nimport takeRight from './takeRight';\nimport takeRightWhile from './takeRightWhile';\nimport takeWhile from './takeWhile';\nimport union from './union';\nimport unionBy from './unionBy';\nimport unionWith from './unionWith';\nimport uniq from './uniq';\nimport uniqBy from './uniqBy';\nimport uniqWith from './uniqWith';\nimport unzip from './unzip';\nimport unzipWith from './unzipWith';\nimport without from './without';\nimport xor from './xor';\nimport xorBy from './xorBy';\nimport xorWith from './xorWith';\nimport zip from './zip';\nimport zipObject from './zipObject';\nimport zipObjectDeep from './zipObjectDeep';\nimport zipWith from './zipWith';\n\nexport default {\n chunk, compact, concat, difference, differenceBy,\n differenceWith, drop, dropRight, dropRightWhile, dropWhile,\n fill, findIndex, findLastIndex, first, flatten,\n flattenDeep, flattenDepth, fromPairs, head, indexOf,\n initial, intersection, intersectionBy, intersectionWith, join,\n last, lastIndexOf, nth, pull, pullAll,\n pullAllBy, pullAllWith, pullAt, remove, reverse,\n slice, sortedIndex, sortedIndexBy, sortedIndexOf, sortedLastIndex,\n sortedLastIndexBy, sortedLastIndexOf, sortedUniq, sortedUniqBy, tail,\n take, takeRight, takeRightWhile, takeWhile, union,\n unionBy, unionWith, uniq, uniqBy, uniqWith,\n unzip, unzipWith, without, xor, xorBy,\n xorWith, zip, zipObject, zipObjectDeep, zipWith\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/array.default.js\n// module id = null\n// module chunks = ","/**\n * Creates an array with all falsey values removed. The values `false`, `null`,\n * `0`, `\"\"`, `undefined`, and `NaN` are falsey.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to compact.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.compact([0, 1, false, 2, '', 3]);\n * // => [1, 2, 3]\n */\nfunction compact(array) {\n var index = -1,\n length = array ? array.length : 0,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (value) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default compact;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/compact.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport baseWhile from './_baseWhile';\n\n/**\n * Creates a slice of `array` excluding elements dropped from the beginning.\n * Elements are dropped until `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Array|Function|Object|string} [predicate=_.identity]\n * The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.dropWhile(users, function(o) { return !o.active; });\n * // => objects for ['pebbles']\n *\n * // The `_.matches` iteratee shorthand.\n * _.dropWhile(users, { 'user': 'barney', 'active': false });\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.dropWhile(users, ['active', false]);\n * // => objects for ['pebbles']\n *\n * // The `_.property` iteratee shorthand.\n * _.dropWhile(users, 'active');\n * // => objects for ['barney', 'fred', 'pebbles']\n */\nfunction dropWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, baseIteratee(predicate, 3), true)\n : [];\n}\n\nexport default dropWhile;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/dropWhile.js\n// module id = null\n// module chunks = ","import baseFindIndex from './_baseFindIndex';\nimport baseIteratee from './_baseIteratee';\n\n/**\n * This method is like `_.findIndex` except that it iterates over elements\n * of `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to search.\n * @param {Array|Function|Object|string} [predicate=_.identity]\n * The function invoked per iteration.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });\n * // => 2\n *\n * // The `_.matches` iteratee shorthand.\n * _.findLastIndex(users, { 'user': 'barney', 'active': true });\n * // => 0\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findLastIndex(users, ['active', false]);\n * // => 2\n *\n * // The `_.property` iteratee shorthand.\n * _.findLastIndex(users, 'active');\n * // => 0\n */\nfunction findLastIndex(array, predicate) {\n return (array && array.length)\n ? baseFindIndex(array, baseIteratee(predicate, 3), true)\n : -1;\n}\n\nexport default findLastIndex;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/findLastIndex.js\n// module id = null\n// module chunks = ","import baseFlatten from './_baseFlatten';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Recursively flattens `array`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flattenDeep([1, [2, [3, [4]], 5]]);\n * // => [1, 2, 3, 4, 5]\n */\nfunction flattenDeep(array) {\n var length = array ? array.length : 0;\n return length ? baseFlatten(array, INFINITY) : [];\n}\n\nexport default flattenDeep;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/flattenDeep.js\n// module id = null\n// module chunks = ","import baseFlatten from './_baseFlatten';\nimport toInteger from './toInteger';\n\n/**\n * Recursively flatten `array` up to `depth` times.\n *\n * @static\n * @memberOf _\n * @since 4.4.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @param {number} [depth=1] The maximum recursion depth.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * var array = [1, [2, [3, [4]], 5]];\n *\n * _.flattenDepth(array, 1);\n * // => [1, 2, [3, [4]], 5]\n *\n * _.flattenDepth(array, 2);\n * // => [1, 2, 3, [4], 5]\n */\nfunction flattenDepth(array, depth) {\n var length = array ? array.length : 0;\n if (!length) {\n return [];\n }\n depth = depth === undefined ? 1 : toInteger(depth);\n return baseFlatten(array, depth);\n}\n\nexport default flattenDepth;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/flattenDepth.js\n// module id = null\n// module chunks = ","/**\n * The inverse of `_.toPairs`; this method returns an object composed\n * from key-value `pairs`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} pairs The key-value pairs.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.fromPairs([['fred', 30], ['barney', 40]]);\n * // => { 'fred': 30, 'barney': 40 }\n */\nfunction fromPairs(pairs) {\n var index = -1,\n length = pairs ? pairs.length : 0,\n result = {};\n\n while (++index < length) {\n var pair = pairs[index];\n result[pair[0]] = pair[1];\n }\n return result;\n}\n\nexport default fromPairs;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/fromPairs.js\n// module id = null\n// module chunks = ","import baseIndexOf from './_baseIndexOf';\nimport toInteger from './toInteger';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * Gets the index at which the first occurrence of `value` is found in `array`\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons. If `fromIndex` is negative, it's used as the\n * offset from the end of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to search.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.indexOf([1, 2, 1, 2], 2);\n * // => 1\n *\n * // Search from the `fromIndex`.\n * _.indexOf([1, 2, 1, 2], 2, 2);\n * // => 3\n */\nfunction indexOf(array, value, fromIndex) {\n var length = array ? array.length : 0;\n if (!length) {\n return -1;\n }\n fromIndex = toInteger(fromIndex);\n if (fromIndex < 0) {\n fromIndex = nativeMax(length + fromIndex, 0);\n }\n return baseIndexOf(array, value, fromIndex);\n}\n\nexport default indexOf;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/indexOf.js\n// module id = null\n// module chunks = ","import dropRight from './dropRight';\n\n/**\n * Gets all but the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.initial([1, 2, 3]);\n * // => [1, 2]\n */\nfunction initial(array) {\n return dropRight(array, 1);\n}\n\nexport default initial;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/initial.js\n// module id = null\n// module chunks = ","import indexOfNaN from './_indexOfNaN';\nimport toInteger from './toInteger';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * This method is like `_.indexOf` except that it iterates over elements of\n * `array` from right to left.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to search.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=array.length-1] The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.lastIndexOf([1, 2, 1, 2], 2);\n * // => 3\n *\n * // Search from the `fromIndex`.\n * _.lastIndexOf([1, 2, 1, 2], 2, 2);\n * // => 1\n */\nfunction lastIndexOf(array, value, fromIndex) {\n var length = array ? array.length : 0;\n if (!length) {\n return -1;\n }\n var index = length;\n if (fromIndex !== undefined) {\n index = toInteger(fromIndex);\n index = (\n index < 0\n ? nativeMax(length + index, 0)\n : nativeMin(index, length - 1)\n ) + 1;\n }\n if (value !== value) {\n return indexOfNaN(array, index, true);\n }\n while (index--) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default lastIndexOf;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/lastIndexOf.js\n// module id = null\n// module chunks = ","import basePullAll from './_basePullAll';\n\n/**\n * This method is like `_.pullAll` except that it accepts `comparator` which\n * is invoked to compare elements of `array` to `values`. The comparator is\n * invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.differenceWith`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];\n *\n * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);\n * console.log(array);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]\n */\nfunction pullAllWith(array, values, comparator) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values, undefined, comparator)\n : array;\n}\n\nexport default pullAllWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/pullAllWith.js\n// module id = null\n// module chunks = ","import baseSlice from './_baseSlice';\nimport isIterateeCall from './_isIterateeCall';\nimport toInteger from './toInteger';\n\n/**\n * Creates a slice of `array` from `start` up to, but not including, `end`.\n *\n * **Note:** This method is used instead of\n * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are\n * returned.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction slice(array, start, end) {\n var length = array ? array.length : 0;\n if (!length) {\n return [];\n }\n if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {\n start = 0;\n end = length;\n }\n else {\n start = start == null ? 0 : toInteger(start);\n end = end === undefined ? length : toInteger(end);\n }\n return baseSlice(array, start, end);\n}\n\nexport default slice;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/slice.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport baseSortedIndexBy from './_baseSortedIndexBy';\n\n/**\n * This method is like `_.sortedIndex` except that it accepts `iteratee`\n * which is invoked for `value` and each element of `array` to compute their\n * sort ranking. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Array|Function|Object|string} [iteratee=_.identity]\n * The iteratee invoked per element.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };\n *\n * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));\n * // => 1\n *\n * // The `_.property` iteratee shorthand.\n * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');\n * // => 0\n */\nfunction sortedIndexBy(array, value, iteratee) {\n return baseSortedIndexBy(array, value, baseIteratee(iteratee));\n}\n\nexport default sortedIndexBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/sortedIndexBy.js\n// module id = null\n// module chunks = ","import baseSortedIndex from './_baseSortedIndex';\nimport eq from './eq';\n\n/**\n * This method is like `_.indexOf` except that it performs a binary\n * search on a sorted `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to search.\n * @param {*} value The value to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.sortedIndexOf([1, 1, 2, 2], 2);\n * // => 2\n */\nfunction sortedIndexOf(array, value) {\n var length = array ? array.length : 0;\n if (length) {\n var index = baseSortedIndex(array, value);\n if (index < length && eq(array[index], value)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default sortedIndexOf;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/sortedIndexOf.js\n// module id = null\n// module chunks = ","import baseSortedIndex from './_baseSortedIndex';\n\n/**\n * This method is like `_.sortedIndex` except that it returns the highest\n * index at which `value` should be inserted into `array` in order to\n * maintain its sort order.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * _.sortedLastIndex([4, 5], 4);\n * // => 1\n */\nfunction sortedLastIndex(array, value) {\n return baseSortedIndex(array, value, true);\n}\n\nexport default sortedLastIndex;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/sortedLastIndex.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport baseSortedIndexBy from './_baseSortedIndexBy';\n\n/**\n * This method is like `_.sortedLastIndex` except that it accepts `iteratee`\n * which is invoked for `value` and each element of `array` to compute their\n * sort ranking. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Array|Function|Object|string} [iteratee=_.identity]\n * The iteratee invoked per element.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * // The `_.property` iteratee shorthand.\n * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');\n * // => 1\n */\nfunction sortedLastIndexBy(array, value, iteratee) {\n return baseSortedIndexBy(array, value, baseIteratee(iteratee), true);\n}\n\nexport default sortedLastIndexBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/sortedLastIndexBy.js\n// module id = null\n// module chunks = ","import baseSortedIndex from './_baseSortedIndex';\nimport eq from './eq';\n\n/**\n * This method is like `_.lastIndexOf` except that it performs a binary\n * search on a sorted `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to search.\n * @param {*} value The value to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.sortedLastIndexOf([1, 1, 2, 2], 2);\n * // => 3\n */\nfunction sortedLastIndexOf(array, value) {\n var length = array ? array.length : 0;\n if (length) {\n var index = baseSortedIndex(array, value, true) - 1;\n if (eq(array[index], value)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default sortedLastIndexOf;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/sortedLastIndexOf.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport baseSortedUniq from './_baseSortedUniq';\n\n/**\n * This method is like `_.uniqBy` except that it's designed and optimized\n * for sorted arrays.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);\n * // => [1.1, 2.3]\n */\nfunction sortedUniqBy(array, iteratee) {\n return (array && array.length)\n ? baseSortedUniq(array, baseIteratee(iteratee))\n : [];\n}\n\nexport default sortedUniqBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/sortedUniqBy.js\n// module id = null\n// module chunks = ","import drop from './drop';\n\n/**\n * Gets all but the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.tail([1, 2, 3]);\n * // => [2, 3]\n */\nfunction tail(array) {\n return drop(array, 1);\n}\n\nexport default tail;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/tail.js\n// module id = null\n// module chunks = ","import baseSlice from './_baseSlice';\nimport toInteger from './toInteger';\n\n/**\n * Creates a slice of `array` with `n` elements taken from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.take([1, 2, 3]);\n * // => [1]\n *\n * _.take([1, 2, 3], 2);\n * // => [1, 2]\n *\n * _.take([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.take([1, 2, 3], 0);\n * // => []\n */\nfunction take(array, n, guard) {\n if (!(array && array.length)) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n return baseSlice(array, 0, n < 0 ? 0 : n);\n}\n\nexport default take;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/take.js\n// module id = null\n// module chunks = ","import baseSlice from './_baseSlice';\nimport toInteger from './toInteger';\n\n/**\n * Creates a slice of `array` with `n` elements taken from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.takeRight([1, 2, 3]);\n * // => [3]\n *\n * _.takeRight([1, 2, 3], 2);\n * // => [2, 3]\n *\n * _.takeRight([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.takeRight([1, 2, 3], 0);\n * // => []\n */\nfunction takeRight(array, n, guard) {\n var length = array ? array.length : 0;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n n = length - n;\n return baseSlice(array, n < 0 ? 0 : n, length);\n}\n\nexport default takeRight;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/takeRight.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport baseWhile from './_baseWhile';\n\n/**\n * Creates a slice of `array` with elements taken from the end. Elements are\n * taken until `predicate` returns falsey. The predicate is invoked with\n * three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Array|Function|Object|string} [predicate=_.identity]\n * The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.takeRightWhile(users, function(o) { return !o.active; });\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.matches` iteratee shorthand.\n * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });\n * // => objects for ['pebbles']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.takeRightWhile(users, ['active', false]);\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.property` iteratee shorthand.\n * _.takeRightWhile(users, 'active');\n * // => []\n */\nfunction takeRightWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, baseIteratee(predicate, 3), false, true)\n : [];\n}\n\nexport default takeRightWhile;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/takeRightWhile.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport baseWhile from './_baseWhile';\n\n/**\n * Creates a slice of `array` with elements taken from the beginning. Elements\n * are taken until `predicate` returns falsey. The predicate is invoked with\n * three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Array|Function|Object|string} [predicate=_.identity]\n * The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false},\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.takeWhile(users, function(o) { return !o.active; });\n * // => objects for ['barney', 'fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.takeWhile(users, { 'user': 'barney', 'active': false });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.takeWhile(users, ['active', false]);\n * // => objects for ['barney', 'fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.takeWhile(users, 'active');\n * // => []\n */\nfunction takeWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, baseIteratee(predicate, 3))\n : [];\n}\n\nexport default takeWhile;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/takeWhile.js\n// module id = null\n// module chunks = ","import baseIteratee from './_baseIteratee';\nimport baseUniq from './_baseUniq';\n\n/**\n * This method is like `_.uniq` except that it accepts `iteratee` which is\n * invoked for each element in `array` to generate the criterion by which\n * uniqueness is computed. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Array|Function|Object|string} [iteratee=_.identity]\n * The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n * // => [2.1, 1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\nfunction uniqBy(array, iteratee) {\n return (array && array.length)\n ? baseUniq(array, baseIteratee(iteratee))\n : [];\n}\n\nexport default uniqBy;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/uniqBy.js\n// module id = null\n// module chunks = ","import baseUniq from './_baseUniq';\n\n/**\n * This method is like `_.uniq` except that it accepts `comparator` which\n * is invoked to compare elements of `array`. The comparator is invoked with\n * two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.uniqWith(objects, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n */\nfunction uniqWith(array, comparator) {\n return (array && array.length)\n ? baseUniq(array, undefined, comparator)\n : [];\n}\n\nexport default uniqWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/uniqWith.js\n// module id = null\n// module chunks = ","export { default as chunk } from './chunk';\nexport { default as compact } from './compact';\nexport { default as concat } from './concat';\nexport { default as difference } from './difference';\nexport { default as differenceBy } from './differenceBy';\nexport { default as differenceWith } from './differenceWith';\nexport { default as drop } from './drop';\nexport { default as dropRight } from './dropRight';\nexport { default as dropRightWhile } from './dropRightWhile';\nexport { default as dropWhile } from './dropWhile';\nexport { default as fill } from './fill';\nexport { default as findIndex } from './findIndex';\nexport { default as findLastIndex } from './findLastIndex';\nexport { default as first } from './first';\nexport { default as flatten } from './flatten';\nexport { default as flattenDeep } from './flattenDeep';\nexport { default as flattenDepth } from './flattenDepth';\nexport { default as fromPairs } from './fromPairs';\nexport { default as head } from './head';\nexport { default as indexOf } from './indexOf';\nexport { default as initial } from './initial';\nexport { default as intersection } from './intersection';\nexport { default as intersectionBy } from './intersectionBy';\nexport { default as intersectionWith } from './intersectionWith';\nexport { default as join } from './join';\nexport { default as last } from './last';\nexport { default as lastIndexOf } from './lastIndexOf';\nexport { default as nth } from './nth';\nexport { default as pull } from './pull';\nexport { default as pullAll } from './pullAll';\nexport { default as pullAllBy } from './pullAllBy';\nexport { default as pullAllWith } from './pullAllWith';\nexport { default as pullAt } from './pullAt';\nexport { default as remove } from './remove';\nexport { default as reverse } from './reverse';\nexport { default as slice } from './slice';\nexport { default as sortedIndex } from './sortedIndex';\nexport { default as sortedIndexBy } from './sortedIndexBy';\nexport { default as sortedIndexOf } from './sortedIndexOf';\nexport { default as sortedLastIndex } from './sortedLastIndex';\nexport { default as sortedLastIndexBy } from './sortedLastIndexBy';\nexport { default as sortedLastIndexOf } from './sortedLastIndexOf';\nexport { default as sortedUniq } from './sortedUniq';\nexport { default as sortedUniqBy } from './sortedUniqBy';\nexport { default as tail } from './tail';\nexport { default as take } from './take';\nexport { default as takeRight } from './takeRight';\nexport { default as takeRightWhile } from './takeRightWhile';\nexport { default as takeWhile } from './takeWhile';\nexport { default as union } from './union';\nexport { default as unionBy } from './unionBy';\nexport { default as unionWith } from './unionWith';\nexport { default as uniq } from './uniq';\nexport { default as uniqBy } from './uniqBy';\nexport { default as uniqWith } from './uniqWith';\nexport { default as unzip } from './unzip';\nexport { default as unzipWith } from './unzipWith';\nexport { default as without } from './without';\nexport { default as xor } from './xor';\nexport { default as xorBy } from './xorBy';\nexport { default as xorWith } from './xorWith';\nexport { default as zip } from './zip';\nexport { default as zipObject } from './zipObject';\nexport { default as zipObjectDeep } from './zipObjectDeep';\nexport { default as zipWith } from './zipWith';\nexport { default as default } from './array.default';\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/array.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/history\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * `History` keeps the track of all the deltas applied to the {@link module:engine/model/document~Document document}.\n */\nexport default class History {\n\t/**\n\t * Creates an empty History instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Deltas added to the history.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/model/delta/delta~Delta>} module:engine/model/history~History#_deltas\n\t\t */\n\t\tthis._deltas = [];\n\n\t\t/**\n\t\t * Helper structure that maps added delta's base version to the index in {@link module:engine/model/history~History#_deltas}\n\t\t * at which the delta was added.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map} module:engine/model/history~History#_historyPoints\n\t\t */\n\t\tthis._historyPoints = new Map();\n\n\t\t/**\n\t\t * Holds an information which {@link module:engine/model/delta/delta~Delta delta} undoes which\n\t\t * {@link module:engine/model/delta/delta~Delta delta}.\n\t\t *\n\t\t * Keys of the map are \"undoing deltas\", that is deltas that undone some other deltas. For each key, the\n\t\t * value is a delta that has been undone by the \"undoing delta\".\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/model/history~History#_undoPairs\n\t\t */\n\t\tthis._undoPairs = new Map();\n\n\t\t/**\n\t\t * Holds all undone deltas.\n\t\t *\n\t\t * @private\n\t\t * @member {Set.<module:engine/model/delta/delta~Delta>} module:engine/model/history~History#_undoneDeltas\n\t\t */\n\t\tthis._undoneDeltas = new Set();\n\t}\n\n\t/**\n\t * Adds delta to the history.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} delta Delta to add.\n\t */\n\taddDelta( delta ) {\n\t\tif ( delta.operations.length > 0 && !this._historyPoints.has( delta.baseVersion ) ) {\n\t\t\tconst index = this._deltas.length;\n\n\t\t\tthis._deltas[ index ] = delta;\n\t\t\tthis._historyPoints.set( delta.baseVersion, index );\n\t\t}\n\t}\n\n\t/**\n\t * Returns deltas added to the history.\n\t *\n\t * @param {Number} [from=0] Base version from which deltas should be returned (inclusive). Defaults to `0`, which means\n\t * that deltas from the first one will be returned.\n\t * @param {Number} [to=Number.POSITIVE_INFINITY] Base version up to which deltas should be returned (exclusive).\n\t * Defaults to `Number.POSITIVE_INFINITY` which means that deltas up to the last one will be returned.\n\t * @returns {Iterator.<module:engine/model/delta/delta~Delta>} Deltas added to the history from given base versions range.\n\t */\n\t* getDeltas( from = 0, to = Number.POSITIVE_INFINITY ) {\n\t\t// No deltas added, nothing to yield.\n\t\tif ( this._deltas.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Will throw if base version is incorrect.\n\t\tlet fromIndex = this._getIndex( from );\n\n\t\t// Base version is too low or too high and is not found in history.\n\t\tif ( fromIndex == -1 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We have correct `fromIndex` so let's iterate starting from it.\n\t\twhile ( fromIndex < this._deltas.length ) {\n\t\t\tconst delta = this._deltas[ fromIndex++ ];\n\n\t\t\tif ( delta.baseVersion >= to ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tyield delta;\n\t\t}\n\t}\n\n\t/**\n\t * Returns delta from history that bases on given `baseVersion`.\n\t *\n\t * @param {Number} baseVersion Base version of the delta to get.\n\t * @returns {module:engine/model/delta/delta~Delta|null} Delta with given base version or `null` if there is no such delta in history.\n\t */\n\tgetDelta( baseVersion ) {\n\t\tconst index = this._historyPoints.get( baseVersion );\n\n\t\treturn index === undefined ? null : this._deltas[ index ];\n\t}\n\n\t/**\n\t * Marks in history that one delta is a delta that is undoing the other delta. By marking deltas this way,\n\t * history is keeping more context information about deltas which helps in operational transformation.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} undoneDelta Delta which is undone by `undoingDelta`.\n\t * @param {module:engine/model/delta/delta~Delta} undoingDelta Delta which undoes `undoneDelta`.\n\t */\n\tsetDeltaAsUndone( undoneDelta, undoingDelta ) {\n\t\tthis._undoPairs.set( undoingDelta, undoneDelta );\n\t\tthis._undoneDeltas.add( undoneDelta );\n\t}\n\n\t/**\n\t * Checks whether given `delta` is undoing by any other delta.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} delta Delta to check.\n\t * @returns {Boolean} `true` if given `delta` is undoing any other delta, `false` otherwise.\n\t */\n\tisUndoingDelta( delta ) {\n\t\treturn this._undoPairs.has( delta );\n\t}\n\n\t/**\n\t * Checks whether given `delta` has been undone by any other delta.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} delta Delta to check.\n\t * @returns {Boolean} `true` if given `delta` has been undone any other delta, `false` otherwise.\n\t */\n\tisUndoneDelta( delta ) {\n\t\treturn this._undoneDeltas.has( delta );\n\t}\n\n\t/**\n\t * For given `undoingDelta`, returns the delta which has been undone by it.\n\t *\n\t * @param {module:engine/model/delta/delta~Delta} undoingDelta\n\t * @returns {module:engine/model/delta/delta~Delta|undefined} Delta that has been undone by given `undoingDelta` or `undefined`\n\t * if given `undoingDelta` is not undoing any other delta.\n\t */\n\tgetUndoneDelta( undoingDelta ) {\n\t\treturn this._undoPairs.get( undoingDelta );\n\t}\n\n\t/**\n\t * Gets an index in {@link module:engine/model/history~History#_deltas} where delta with given `baseVersion` is added.\n\t *\n\t * @private\n\t * @param {Number} baseVersion Base version of delta.\n\t */\n\t_getIndex( baseVersion ) {\n\t\tconst index = this._historyPoints.get( baseVersion );\n\n\t\t// Base version not found - it is either too high or too low, or is in the middle of delta.\n\t\tif ( index === undefined ) {\n\t\t\tconst lastDelta = this._deltas[ this._deltas.length - 1 ];\n\t\t\tconst nextBaseVersion = lastDelta.baseVersion + lastDelta.operations.length;\n\n\t\t\tif ( baseVersion < 0 || baseVersion >= nextBaseVersion ) {\n\t\t\t\t// Base version is too high or too low - it's acceptable situation.\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Given base version points to the middle of a delta.\n\t\t\t *\n\t\t\t * @error history-wrong-version\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-history-wrong-version: Given base version points to the middle of a delta.' );\n\t\t}\n\n\t\treturn index;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/model/history.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/editingkeystrokehandler\n */\n\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n\n/**\n * A keystroke handler for editor editing. Its instance is available\n * in {@link module:core/editor/standardeditor~StandardEditor#keystrokes} so plugins\n * can register their keystrokes.\n *\n * E.g. an undo plugin would do this:\n *\n *\t\teditor.keystrokes.set( 'Ctrl+Z', 'undo' );\n *\t\teditor.keystrokes.set( 'Ctrl+Shift+Z', 'redo' );\n *\t\teditor.keystrokes.set( 'Ctrl+Y', 'redo' );\n *\n * @extends utils/keystrokehandler~KeystrokeHandler\n */\nexport default class EditingKeystrokeHandler extends KeystrokeHandler {\n\t/**\n\t * Creates an instance of the keystroke handler.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t */\n\tconstructor( editor ) {\n\t\tsuper();\n\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * The handler can be specified as a command name or a callback.\n\t *\n\t * @param {String|Array.<String|Number>} keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param {Function|String} callback If a string is passed, then the keystroke will\n\t * {@link module:core/editor/editor~Editor#execute execute a command}.\n\t * If a function, then it will be called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a `cancel()` helper to both `preventDefault()` and `stopPropagation()` of the event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of the keystroke\n\t * callback. The higher the priority value the sooner the callback will be executed. Keystrokes having the same priority\n\t * are called in the order they were added.\n\t */\n\tset( keystroke, callback, options = {} ) {\n\t\tif ( typeof callback == 'string' ) {\n\t\t\tconst commandName = callback;\n\n\t\t\tcallback = ( evtData, cancel ) => {\n\t\t\t\tthis.editor.execute( commandName );\n\t\t\t\tcancel();\n\t\t\t};\n\t\t}\n\n\t\tsuper.set( keystroke, callback, options );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/src/editingkeystrokehandler.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/observer\n */\n\nimport DomEmitterMixin from '@ckeditor/ckeditor5-utils/src/dom/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Abstract base observer class. Observers are classes which observe changes on DOM elements, do the preliminary\n * processing and fire events on the {@link module:engine/view/document~Document} objects. Observers can also add features to the view,\n * for instance by updating its status or marking elements which need refresh on DOM events.\n *\n * @abstract\n */\nexport default class Observer {\n\t/**\n\t * Creates an instance of the observer.\n\t *\n\t * @param {module:engine/view/document~Document} document\n\t */\n\tconstructor( document ) {\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/document~Document} object.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/document~Document}\n\t\t */\n\t\tthis.document = document;\n\n\t\t/**\n\t\t * State of the observer. If it is disabled events will not be fired.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.isEnabled = false;\n\t}\n\n\t/**\n\t * Enables the observer. This method is called when then observer is registered to the\n\t * {@link module:engine/view/document~Document} and after {@link module:engine/view/document~Document#render 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\n\t/**\n\t * Disables the observer. This method is called before\n\t * {@link module:engine/view/document~Document#render 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\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\n\t/**\n\t * Starts observing the given root element.\n\t *\n\t * @method #observe\n\t * @param {HTMLElement} domElement\n\t * @param {String} name The name of the root element.\n\t */\n}\n\nmix( Observer, DomEmitterMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/observer.js\n// module id = null\n// module chunks = ","import baseIsEqual from './_baseIsEqual';\n\n/**\n * This method is like `_.isEqual` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with up to\n * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if the values are equivalent,\n * else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, othValue) {\n * if (isGreeting(objValue) && isGreeting(othValue)) {\n * return true;\n * }\n * }\n *\n * var array = ['hello', 'goodbye'];\n * var other = ['hi', 'goodbye'];\n *\n * _.isEqualWith(array, other, customizer);\n * // => true\n */\nfunction isEqualWith(value, other, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n var result = customizer ? customizer(value, other) : undefined;\n return result === undefined ? baseIsEqual(value, other, customizer) : !!result;\n}\n\nexport default isEqualWith;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isEqualWith.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/mutationobserver\n */\n\n/* globals window */\n\nimport Observer from './observer';\nimport ViewSelection from '../selection';\nimport { startsWithFiller, getDataWithoutFiller } from '../filler';\nimport isEqualWith from '@ckeditor/ckeditor5-utils/src/lib/lodash/isEqualWith';\n\n/**\n * Mutation observer class observes changes in the DOM, fires {@link module:engine/view/document~Document#event:mutations} event, mark view\n * elements as changed and call {@link module:engine/view/renderer~Renderer#render}.\n * Because all mutated nodes are marked as \"to be rendered\" and the\n * {@link module:engine/view/renderer~Renderer#render} is called, all changes will be reverted, unless the mutation will be handled by the\n * {@link module:engine/view/document~Document#event:mutations} event listener. It means user will see only handled changes, and the editor\n * will block all changes which are not handled.\n *\n * Mutation Observer also take care of reducing number of mutations which are fired. It removes duplicates and\n * mutations on elements which do not have corresponding view elements. Also\n * {@link module:engine/view/observer/mutationobserver~MutatedText text mutation} is fired only if parent element do not change child list.\n *\n * Note that this observer is attached by the {@link module:engine/view/document~Document} and is available by default.\n *\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class MutationObserver extends Observer {\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\t/**\n\t\t * Native mutation observer config.\n\t\t *\n\t\t * @private\n\t\t * @member {Object}\n\t\t */\n\t\tthis._config = {\n\t\t\tchildList: true,\n\t\t\tcharacterData: true,\n\t\t\tcharacterDataOldValue: true,\n\t\t\tsubtree: true\n\t\t};\n\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/document~Document#domConverter}.\n\t\t *\n\t\t * @member {module:engine/view/domconverter~DomConverter}\n\t\t */\n\t\tthis.domConverter = document.domConverter;\n\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/document~Document#renderer}.\n\t\t *\n\t\t * @member {module:engine/view/renderer~Renderer}\n\t\t */\n\t\tthis.renderer = document.renderer;\n\n\t\t/**\n\t\t * Observed DOM elements.\n\t\t *\n\t\t * @private\n\t\t * @member {Array.<HTMLElement>}\n\t\t */\n\t\tthis._domElements = [];\n\n\t\t/**\n\t\t * Native mutation observer.\n\t\t *\n\t\t * @private\n\t\t * @member {MutationObserver}\n\t\t */\n\t\tthis._mutationObserver = new window.MutationObserver( this._onMutations.bind( this ) );\n\t}\n\n\t/**\n\t * Synchronously fires {@link module:engine/view/document~Document#event:mutations} event with all mutations in record queue.\n\t * At the same time empties the queue so mutations will not be fired twice.\n\t */\n\tflush() {\n\t\tthis._onMutations( this._mutationObserver.takeRecords() );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve( domElement ) {\n\t\tthis._domElements.push( domElement );\n\n\t\tif ( this.isEnabled ) {\n\t\t\tthis._mutationObserver.observe( domElement, this._config );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tenable() {\n\t\tsuper.enable();\n\n\t\tfor ( const domElement of this._domElements ) {\n\t\t\tthis._mutationObserver.observe( domElement, this._config );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisable() {\n\t\tsuper.disable();\n\n\t\tthis._mutationObserver.disconnect();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tthis._mutationObserver.disconnect();\n\t}\n\n\t/**\n\t * Handles mutations. Deduplicates, mark view elements to sync, fire event and call render.\n\t *\n\t * @private\n\t * @param {Array.<Object>} domMutations Array of native mutations.\n\t */\n\t_onMutations( domMutations ) {\n\t\t// As a result of this.flush() we can have an empty collection.\n\t\tif ( domMutations.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domConverter = this.domConverter;\n\n\t\t// Use map and set for deduplication.\n\t\tconst mutatedTexts = new Map();\n\t\tconst mutatedElements = new Set();\n\n\t\t// Handle `childList` mutations first, so we will be able to check if the `characterData` mutation is in the\n\t\t// element with changed structure anyway.\n\t\tfor ( const mutation of domMutations ) {\n\t\t\tif ( mutation.type === 'childList' ) {\n\t\t\t\tconst element = domConverter.mapDomToView( mutation.target );\n\n\t\t\t\t// Do not collect mutations from UIElements.\n\t\t\t\tif ( element && element.is( 'uiElement' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( element && !this._isBogusBrMutation( mutation ) ) {\n\t\t\t\t\tmutatedElements.add( element );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Handle `characterData` mutations later, when we have the full list of nodes which changed structure.\n\t\tfor ( const mutation of domMutations ) {\n\t\t\tconst element = domConverter.mapDomToView( mutation.target );\n\n\t\t\t// Do not collect mutations from UIElements.\n\t\t\tif ( element && element.is( 'uiElement' ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( mutation.type === 'characterData' ) {\n\t\t\t\tconst text = domConverter.findCorrespondingViewText( mutation.target );\n\n\t\t\t\tif ( text && !mutatedElements.has( text.parent ) ) {\n\t\t\t\t\t// Use text as a key, for deduplication. If there will be another mutation on the same text element\n\t\t\t\t\t// we will have only one in the map.\n\t\t\t\t\tmutatedTexts.set( text, {\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\toldText: text.data,\n\t\t\t\t\t\tnewText: getDataWithoutFiller( mutation.target ),\n\t\t\t\t\t\tnode: text\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\t// When we added first letter to the text node which had only inline filler, for the DOM it is mutation\n\t\t\t\t// on text, but for the view, where filler text node did not existed, new text node was created, so we\n\t\t\t\t// need to fire 'children' mutation instead of 'text'.\n\t\t\t\telse if ( !text && startsWithFiller( mutation.target ) ) {\n\t\t\t\t\tmutatedElements.add( domConverter.mapDomToView( mutation.target.parentNode ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Now we build the list of mutations to fire and mark elements. We did not do it earlier to avoid marking the\n\t\t// same node multiple times in case of duplication.\n\n\t\t// List of mutations we will fire.\n\t\tconst viewMutations = [];\n\n\t\tfor ( const mutatedText of mutatedTexts.values() ) {\n\t\t\tthis.renderer.markToSync( 'text', mutatedText.node );\n\t\t\tviewMutations.push( mutatedText );\n\t\t}\n\n\t\tfor ( const viewElement of mutatedElements ) {\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 ) );\n\n\t\t\t// It may happen that as a result of many changes (sth was inserted and then removed),\n\t\t\t// both elements haven't really changed. #1031\n\t\t\tif ( !isEqualWith( viewChildren, newViewChildren, sameNodes ) ) {\n\t\t\t\tthis.renderer.markToSync( 'children', viewElement );\n\n\t\t\t\tviewMutations.push( {\n\t\t\t\t\ttype: 'children',\n\t\t\t\t\toldChildren: viewChildren,\n\t\t\t\t\tnewChildren: newViewChildren,\n\t\t\t\t\tnode: viewElement\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t\t// Retrieve `domSelection` using `ownerDocument` of one of mutated nodes.\n\t\t// There should not be simultaneous mutation in multiple documents, so it's fine.\n\t\tconst domSelection = domMutations[ 0 ].target.ownerDocument.getSelection();\n\n\t\tlet viewSelection = null;\n\n\t\tif ( domSelection && domSelection.anchorNode ) {\n\t\t\t// If `domSelection` is inside a dom node that is already bound to a view node from view tree, get\n\t\t\t// corresponding selection in the view and pass it together with `viewMutations`. The `viewSelection` may\n\t\t\t// be used by features handling mutations.\n\t\t\t// Only one range is supported.\n\n\t\t\tconst viewSelectionAnchor = domConverter.domPositionToView( domSelection.anchorNode, domSelection.anchorOffset );\n\t\t\tconst viewSelectionFocus = domConverter.domPositionToView( domSelection.focusNode, domSelection.focusOffset );\n\n\t\t\t// Anchor and focus has to be properly mapped to view.\n\t\t\tif ( viewSelectionAnchor && viewSelectionFocus ) {\n\t\t\t\tviewSelection = new ViewSelection();\n\t\t\t\tviewSelection.setCollapsedAt( viewSelectionAnchor );\n\t\t\t\tviewSelection.moveFocusTo( viewSelectionFocus );\n\t\t\t}\n\t\t}\n\n\t\tthis.document.fire( 'mutations', viewMutations, viewSelection );\n\n\t\t// If nothing changes on `mutations` event, at this point we have \"dirty DOM\" (changed) and de-synched\n\t\t// view (which has not been changed). In order to \"reset DOM\" we render the view again.\n\t\tthis.document.render();\n\n\t\tfunction sameNodes( child1, child2 ) {\n\t\t\t// First level of comparison (array of children vs array of children) use the Lodash's default behavior.\n\t\t\tif ( Array.isArray( child1 ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Elements.\n\t\t\tif ( child1 === child2 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t// Texts.\n\t\t\telse if ( child1.is( 'text' ) && child2.is( 'text' ) ) {\n\t\t\t\treturn child1.data === child2.data;\n\t\t\t}\n\n\t\t\t// Not matching types.\n\t\t\treturn false;\n\t\t}\n\t}\n\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 * @private\n\t * @param {Object} mutation Native mutation object.\n\t * @returns {Boolean}\n\t */\n\t_isBogusBrMutation( mutation ) {\n\t\tlet addedNode = null;\n\n\t\t// Check if mutation added only one node on the end of its parent.\n\t\tif ( mutation.nextSibling === null && mutation.removedNodes.length === 0 && mutation.addedNodes.length == 1 ) {\n\t\t\taddedNode = this.domConverter.domToView( mutation.addedNodes[ 0 ], {\n\t\t\t\twithChildren: false\n\t\t\t} );\n\t\t}\n\n\t\treturn addedNode && addedNode.is( 'element', 'br' );\n\t}\n}\n\n/**\n * Fired when mutation occurred. If tree view is not changed on this event, DOM will be reverter to the state before\n * mutation, so all changes which should be applied, should be handled on this event.\n *\n * Introduced by {@link module:engine/view/observer/mutationobserver~MutationObserver}.\n *\n * Note that because {@link module:engine/view/observer/mutationobserver~MutationObserver} is attached by the\n * {@link module:engine/view/document~Document}\n * this event is available by default.\n *\n * @see module:engine/view/observer/mutationobserver~MutationObserver\n * @event module:engine/view/document~Document#event:mutations\n * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|module:engine/view/observer/mutationobserver~MutatedChildren>}\n * viewMutations Array of mutations.\n * For mutated texts it will be {@link module:engine/view/observer/mutationobserver~MutatedText} and for mutated elements it will be\n * {@link module:engine/view/observer/mutationobserver~MutatedChildren}. You can recognize the type based on the `type` property.\n * @param {module:engine/view/selection~Selection|null} viewSelection View selection that is a result of converting DOM selection to view.\n * Keep in\n * mind that the DOM selection is already \"updated\", meaning that it already acknowledges changes done in mutation.\n */\n\n/**\n * Mutation item for text.\n *\n * @see module:engine/view/document~Document#event:mutations\n * @see module:engine/view/observer/mutationobserver~MutatedChildren\n *\n * @typedef {Object} module:engine/view/observer/mutationobserver~MutatedText\n *\n * @property {String} type For text mutations it is always 'text'.\n * @property {module:engine/view/text~Text} node Mutated text node.\n * @property {String} oldText Old text.\n * @property {String} newText New text.\n */\n\n/**\n * Mutation item for child nodes.\n *\n * @see module:engine/view/document~Document#event:mutations\n * @see module:engine/view/observer/mutationobserver~MutatedText\n *\n * @typedef {Object} module:engine/view/observer/mutationobserver~MutatedChildren\n *\n * @property {String} type For child nodes mutations it is always 'children'.\n * @property {module:engine/view/element~Element} node Parent of the mutated children.\n * @property {Array.<module:engine/view/node~Node>} oldChildren Old child nodes.\n * @property {Array.<module:engine/view/node~Node>} newChildren New child nodes.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/mutationobserver.js\n// module id = null\n// module chunks = ","/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @type {Function}\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred function to be invoked.\n */\nvar now = Date.now;\n\nexport default now;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/now.js\n// module id = null\n// module chunks = ","import isObject from './isObject';\nimport now from './now';\nimport toNumber from './toNumber';\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide an options object to indicate whether `func` should be invoked on\n * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent calls\n * to the debounced function return the result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the debounced function is\n * invoked more than once during the `wait` timeout.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime = 0,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n result = wait - timeSinceLastCall;\n\n return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (!lastCallTime || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n clearTimeout(timerId);\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastCallTime = lastInvokeTime = 0;\n lastArgs = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\nexport default debounce;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/debounce.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/selectionobserver\n */\n\n/* global setInterval, clearInterval */\n\nimport Observer from './observer';\nimport MutationObserver from './mutationobserver';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport debounce from '@ckeditor/ckeditor5-utils/src/lib/lodash/debounce';\n\n/**\n * Selection observer class observes selection changes in the document. If selection changes on the document this\n * observer checks if there are any mutations and if DOM selection is different than the\n * {@link module:engine/view/document~Document#selection view selection}. Selection observer fires\n * {@link module:engine/view/document~Document#event:selectionChange} event only if selection change was the only change in the document\n * and DOM selection is different then the view selection.\n *\n * Note that this observer is attached by the {@link module:engine/view/document~Document} and is available by default.\n *\n * @see module:engine/view/observer/mutationobserver~MutationObserver\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class SelectionObserver extends Observer {\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\t/**\n\t\t * Instance of the mutation observer. Selection observer calls\n\t\t * {@link module:engine/view/observer/mutationobserver~MutationObserver#flush} to ensure that the mutations will be handled\n\t\t * before the {@link module:engine/view/document~Document#event:selectionChange} event is fired.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/observer/mutationobserver~MutationObserver}\n\t\t * module:engine/view/observer/selectionobserver~SelectionObserver#mutationObserver\n\t\t */\n\t\tthis.mutationObserver = document.getObserver( MutationObserver );\n\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/document~Document} object.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/document~Document} module:engine/view/observer/selectionobserver~SelectionObserver#document\n\t\t */\n\t\tthis.document = document;\n\n\t\t/**\n\t\t * Reference to the view {@link module:engine/view/selection~Selection} object used to compare new selection with it.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/selection~Selection} module:engine/view/observer/selectionobserver~SelectionObserver#selection\n\t\t */\n\t\tthis.selection = document.selection;\n\n\t\t/* eslint-disable max-len */\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/document~Document#domConverter}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/domconverter~DomConverter} module:engine/view/observer/selectionobserver~SelectionObserver#domConverter\n\t\t */\n\t\t/* eslint-enable max-len */\n\t\tthis.domConverter = document.domConverter;\n\n\t\t/**\n\t\t * Set of documents which have added \"selectionchange\" listener to avoid adding listener twice to the same\n\t\t * document.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakSet.<Document>} module:engine/view/observer/selectionobserver~SelectionObserver#_documents\n\t\t */\n\t\tthis._documents = new WeakSet();\n\n\t\t/**\n\t\t * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.\n\t\t *\n\t\t * @private\n\t\t * @param {Object} data Selection change data.\n\t\t * @method #_fireSelectionChangeDoneDebounced\n\t\t */\n\t\tthis._fireSelectionChangeDoneDebounced = debounce( data => this.document.fire( 'selectionChangeDone', data ), 200 );\n\n\t\tthis._clearInfiniteLoopInterval = setInterval( () => this._clearInfiniteLoop(), 1000 );\n\n\t\t/**\n\t\t * Private property to check if the code does not enter infinite loop.\n\t\t *\n\t\t * @private\n\t\t * @member {Number} module:engine/view/observer/selectionobserver~SelectionObserver#_loopbackCounter\n\t\t */\n\t\tthis._loopbackCounter = 0;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve( domElement ) {\n\t\tconst domDocument = domElement.ownerDocument;\n\n\t\t// Add listener once per each document.\n\t\tif ( this._documents.has( domDocument ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.listenTo( domDocument, 'selectionchange', () => {\n\t\t\tthis._handleSelectionChange( domDocument );\n\t\t} );\n\n\t\tthis._documents.add( domDocument );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tclearInterval( this._clearInfiniteLoopInterval );\n\t\tthis._fireSelectionChangeDoneDebounced.cancel();\n\t}\n\n\t/**\n\t * Selection change listener. {@link module:engine/view/observer/mutationobserver~MutationObserver#flush Flush} mutations, check if\n\t * selection changes and fires {@link module:engine/view/document~Document#event:selectionChange} event on every change\n\t * and {@link module:engine/view/document~Document#event:selectionChangeDone} when selection stop changing.\n\t *\n\t * @private\n\t * @param {Document} domDocument DOM document.\n\t */\n\t_handleSelectionChange( domDocument ) {\n\t\t// Selection is handled when document is not focused but is read-only. This is because in read-only\n\t\t// mode contenteditable is set as false and editor won't receive focus but we still need to know\n\t\t// selection position.\n\t\tif ( !this.isEnabled || ( !this.document.isFocused && !this.document.isReadOnly ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ensure the mutation event will be before selection event on all browsers.\n\t\tthis.mutationObserver.flush();\n\n\t\t// If there were mutations then the view will be re-rendered by the mutation observer and selection\n\t\t// will be updated, so selections will equal and event will not be fired, as expected.\n\t\tconst domSelection = domDocument.defaultView.getSelection();\n\t\tconst newViewSelection = this.domConverter.domSelectionToView( domSelection );\n\n\t\tif ( this.selection.isEqual( newViewSelection ) && this.domConverter.isDomSelectionCorrect( domSelection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ensure we are not in the infinite loop (#400).\n\t\t// This counter is reset each second. 60 selection changes in 1 second is enough high number\n\t\t// to be very difficult (impossible) to achieve using just keyboard keys (during normal editor use).\n\t\tif ( ++this._loopbackCounter > 60 ) {\n\t\t\t/**\n\t\t\t * Selection change observer detected an infinite rendering loop.\n\t\t\t * Most probably you try to put the selection in the position which is not allowed\n\t\t\t * by the browser and browser fixes it automatically what causes `selectionchange` event on\n\t\t\t * which a loopback through a model tries to re-render the wrong selection and again.\n\t\t\t *\n\t\t\t * @error selectionchange-infinite-loop\n\t\t\t */\n\t\t\tlog.warn( 'selectionchange-infinite-loop: Selection change observer detected an infinite rendering loop.' );\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.selection.isSimilar( newViewSelection ) ) {\n\t\t\t// If selection was equal and we are at this point of algorithm, it means that it was incorrect.\n\t\t\t// Just re-render it, no need to fire any events, etc.\n\t\t\tthis.document.render();\n\t\t} else {\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\n\t\t\t// Prepare data for new selection and fire appropriate events.\n\t\t\tthis.document.fire( 'selectionChange', data );\n\n\t\t\t// Call` #_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.\n\t\t\t// This function is debounced what means that `selectionChangeDone` event will be fired only when\n\t\t\t// defined int the function time will elapse since the last time the function was called.\n\t\t\t// So `selectionChangeDone` will be fired when selection will stop changing.\n\t\t\tthis._fireSelectionChangeDoneDebounced( data );\n\t\t}\n\t}\n\n\t/**\n\t * Clears `SelectionObserver` internal properties connected with preventing infinite loop.\n\t *\n\t * @protected\n\t */\n\t_clearInfiniteLoop() {\n\t\tthis._loopbackCounter = 0;\n\t}\n}\n\n/**\n * Fired when selection has changed. This event is fired only when the selection change was the only change that happened\n * in the document, and old selection is different then the new selection.\n *\n * Introduced by {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n *\n * Note that because {@link module:engine/view/observer/selectionobserver~SelectionObserver} is attached by the\n * {@link module:engine/view/document~Document}\n * this event is available by default.\n *\n * @see module:engine/view/observer/selectionobserver~SelectionObserver\n * @event module:engine/view/document~Document#event:selectionChange\n * @param {Object} data\n * @param {module:engine/view/selection~Selection} data.oldSelection Old View selection which is\n * {@link module:engine/view/document~Document#selection}.\n * @param {module:engine/view/selection~Selection} data.newSelection New View selection which is converted DOM selection.\n * @param {Selection} data.domSelection Native DOM selection.\n */\n\n/**\n * Fired when selection stops changing.\n *\n * Introduced by {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n *\n * Note that because {@link module:engine/view/observer/selectionobserver~SelectionObserver} is attached by the\n * {@link module:engine/view/document~Document}\n * this event is available by default.\n *\n * @see module:engine/view/observer/selectionobserver~SelectionObserver\n * @event module:engine/view/document~Document#event:selectionChangeDone\n * @param {Object} data\n * @param {module:engine/view/selection~Selection} data.oldSelection Old View selection which is\n * {@link module:engine/view/document~Document#selection}.\n * @param {module:engine/view/selection~Selection} data.newSelection New View selection which is converted DOM selection.\n * @param {Selection} data.domSelection Native DOM selection.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/selectionobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/domeventdata\n */\n\nimport extend from '@ckeditor/ckeditor5-utils/src/lib/lodash/extend';\n\n/**\n * Information about a DOM event in context of the {@link module:engine/view/document~Document}.\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 */\nexport default class DomEventData {\n\t/**\n\t * @param {module:engine/view/document~Document} document The instance of the tree view Document.\n\t * @param {Event} domEvent The DOM event.\n\t * @param {Object} [additionalData] Additional properties that the instance should contain.\n\t */\n\tconstructor( document, domEvent, additionalData ) {\n\t\t/**\n\t\t * The instance of the document.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/document~Document} module:engine/view/observer/observer~Observer.DomEvent#view\n\t\t */\n\t\tthis.document = document;\n\n\t\t/**\n\t\t * The DOM event.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Event} module:engine/view/observer/observer~Observer.DomEvent#domEvent\n\t\t */\n\t\tthis.domEvent = domEvent;\n\n\t\t/**\n\t\t * The DOM target.\n\t\t *\n\t\t * @readonly\n\t\t * @member {HTMLElement} module:engine/view/observer/observer~Observer.DomEvent#target\n\t\t */\n\t\tthis.domTarget = domEvent.target;\n\n\t\textend( this, additionalData );\n\t}\n\n\t/**\n\t * The tree view element representing the target.\n\t *\n\t * @readonly\n\t * @type module:engine/view/element~Element\n\t */\n\tget target() {\n\t\treturn this.document.domConverter.mapDomToView( this.domTarget );\n\t}\n\n\t/**\n\t * Prevents the native's event default action.\n\t */\n\tpreventDefault() {\n\t\tthis.domEvent.preventDefault();\n\t}\n\n\t/**\n\t * Stops native event propagation.\n\t */\n\tstopPropagation() {\n\t\tthis.domEvent.stopPropagation();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/domeventdata.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/domeventobserver\n */\n\nimport Observer from './observer';\nimport DomEventData from './domeventdata';\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 *\t\tclass ClickObserver extends DomEventObserver {\n *\t\t\t// It can also be defined as a normal property in the constructor.\n *\t\t\tget domEventType() {\n *\t\t\t\treturn 'click';\n *\t\t\t}\n *\n *\t\t\tonDomEvent( domEvent ) {\n *\t\t\t\tthis.fire( 'click', domEvent );\n *\t\t\t}\n *\t\t}\n *\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class DomEventObserver extends Observer {\n\t/**\n\t * Type of the DOM event the observer should listen on. Array of types can be defined\n\t * if the obsever should listen to multiple DOM events.\n\t *\n\t * @readonly\n\t * @member {String|Array.<String>} #domEventType\n\t */\n\n\t/**\n\t * Callback which should be called when the DOM event occurred. Note that the callback will not be called if\n\t * observer {@link #isEnabled is not enabled}.\n\t *\n\t * @see #domEventType\n\t * @abstract\n\t * @method #onDomEvent\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\t/**\n\t\t * If set to `true` DOM events will be listened on the capturing phase.\n\t\t * Default value is `false`.\n\t\t *\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.useCapture = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve( domElement ) {\n\t\tconst types = typeof this.domEventType == 'string' ? [ this.domEventType ] : this.domEventType;\n\n\t\ttypes.forEach( type => {\n\t\t\tthis.listenTo( domElement, type, ( eventInfo, domEvent ) => {\n\t\t\t\tif ( this.isEnabled ) {\n\t\t\t\t\tthis.onDomEvent( domEvent );\n\t\t\t\t}\n\t\t\t}, { useCapture: this.useCapture } );\n\t\t} );\n\t}\n\n\t/**\n\t * Calls `Document#fire()` if observer {@link #isEnabled is enabled}.\n\t *\n\t * @see module:utils/emittermixin~EmitterMixin#fire\n\t * @param {String} eventType The event type (name).\n\t * @param {Event} domEvent The DOM event.\n\t * @param {Object} [additionalData] The additional data which should extend the\n\t * {@link module:engine/view/observer/domeventdata~DomEventData event data} object.\n\t */\n\tfire( eventType, domEvent, additionalData ) {\n\t\tif ( this.isEnabled ) {\n\t\t\tthis.document.fire( eventType, new DomEventData( this.document, domEvent, additionalData ) );\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/domeventobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/focusobserver\n */\n\n/* globals setTimeout, clearTimeout */\n\nimport DomEventObserver from './domeventobserver';\n\n/**\n * {@link module:engine/view/document~Document#event:focus Focus}\n * and {@link module:engine/view/document~Document#event:blur blur} events observer.\n * Focus observer handle also {@link module:engine/view/rooteditableelement~RootEditableElement#isFocused isFocused} property of the\n * {@link module:engine/view/rooteditableelement~RootEditableElement root elements}.\n *\n * Note that this observer is attached by the {@link module:engine/view/document~Document} and is available by default.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class FocusObserver extends DomEventObserver {\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\tthis.domEventType = [ 'focus', 'blur' ];\n\t\tthis.useCapture = true;\n\n\t\tdocument.on( 'focus', () => {\n\t\t\tdocument.isFocused = true;\n\n\t\t\t// Unfortunately native `selectionchange` event is fired asynchronously.\n\t\t\t// We need to wait until `SelectionObserver` handle the event and then render. Otherwise rendering will\n\t\t\t// overwrite new DOM selection with selection from the view.\n\t\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/795 for more details.\n\t\t\tthis._renderTimeoutId = setTimeout( () => document.render(), 0 );\n\t\t} );\n\n\t\tdocument.on( 'blur', ( evt, data ) => {\n\t\t\tconst selectedEditable = document.selection.editableElement;\n\n\t\t\tif ( selectedEditable === null || selectedEditable === data.target ) {\n\t\t\t\tdocument.isFocused = false;\n\n\t\t\t\t// Re-render the document to update view elements.\n\t\t\t\tdocument.render();\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Identifier of the timeout currently used by focus listener to delay rendering execution.\n\t\t *\n\t\t * @private\n\t\t * @member {Number} #_renderTimeoutId\n\t\t */\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tif ( this._renderTimeoutId ) {\n\t\t\tclearTimeout( this._renderTimeoutId );\n\t\t}\n\n\t\tsuper.destroy();\n\t}\n}\n\n/**\n * Fired when one of the editables gets focus.\n *\n * Introduced by {@link module:engine/view/observer/focusobserver~FocusObserver}.\n *\n * Note that because {@link module:engine/view/observer/focusobserver~FocusObserver} is attached by the\n * {@link module:engine/view/document~Document}\n * this event is available by default.\n *\n * @see module:engine/view/observer/focusobserver~FocusObserver\n * @event module:engine/view/document~Document#event:focus\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n\n/**\n * Fired when one of the editables loses focus.\n *\n * Introduced by {@link module:engine/view/observer/focusobserver~FocusObserver}.\n *\n * Note that because {@link module:engine/view/observer/focusobserver~FocusObserver} is attached by the\n * {@link module:engine/view/document~Document}\n * this event is available by default.\n *\n * @see module:engine/view/observer/focusobserver~FocusObserver\n * @event module:engine/view/document~Document#event:blur\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/focusobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/keyobserver\n */\n\nimport DomEventObserver from './domeventobserver';\nimport { getCode } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * {@link module:engine/view/document~Document#event:keydown Key down} event observer.\n *\n * Note that this observer is attached by the {@link module:engine/view/document~Document} and is available by default.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class KeyObserver extends DomEventObserver {\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\tthis.domEventType = [ 'keydown', 'keyup' ];\n\t}\n\n\tonDomEvent( domEvt ) {\n\t\tthis.fire( domEvt.type, domEvt, {\n\t\t\tkeyCode: domEvt.keyCode,\n\n\t\t\taltKey: domEvt.altKey,\n\t\t\tctrlKey: domEvt.ctrlKey || domEvt.metaKey,\n\t\t\tshiftKey: domEvt.shiftKey,\n\n\t\t\tget keystroke() {\n\t\t\t\treturn getCode( this );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Fired when a key has been pressed.\n *\n * Introduced by {@link module:engine/view/observer/keyobserver~KeyObserver}.\n *\n * Note that because {@link module:engine/view/observer/keyobserver~KeyObserver} is attached by the\n * {@link module:engine/view/document~Document}\n * this event is available by default.\n *\n * @see module:engine/view/observer/keyobserver~KeyObserver\n * @event module:engine/view/document~Document#event:keydown\n * @param {module:engine/view/observer/keyobserver~KeyEventData} keyEventData\n */\n\n/**\n * Fired when a key has been released.\n *\n * Introduced by {@link module:engine/view/observer/keyobserver~KeyObserver}.\n *\n * Note that because {@link module:engine/view/observer/keyobserver~KeyObserver} is attached by the\n * {@link module:engine/view/document~Document}\n * this event is available by default.\n *\n * @see module:engine/view/observer/keyobserver~KeyObserver\n * @event module:engine/view/document~Document#event:keyup\n * @param {module:engine/view/observer/keyobserver~KeyEventData} keyEventData\n */\n\n/**\n * The value of both events - {@link module:engine/view/document~Document#event:keydown} and\n * {@link module:engine/view/document~Document#event:keyup}.\n *\n * @class module:engine/view/observer/keyobserver~KeyEventData\n * @extends module:engine/view/observer/domeventdata~DomEventData\n * @implements module:utils/keyboard~KeystrokeInfo\n */\n\n/**\n * Code of the whole keystroke. See {@link module:utils/keyboard~getCode}.\n *\n * @readonly\n * @member {Number} module:engine/view/observer/keyobserver~KeyEventData#keystroke\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/keyobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/dataprocessor/basichtmlwriter\n */\n\n/* globals document */\n\n/**\n * Basic HTML writer, it uses the native `innerHTML` property for basic conversion\n * from DocumentFragment to an HTML string.\n *\n * @implements module:engine/dataprocessor/htmlwriter~HtmlWriter\n */\nexport default class BasicHtmlWriter {\n\t/**\n\t * Returns HTML string created from DocumentFragment.\n\t *\n\t * @param {DocumentFragment} fragment\n\t * @returns {String}\n\t */\n\tgetHtml( fragment ) {\n\t\tconst doc = document.implementation.createHTMLDocument( '' );\n\t\tconst container = doc.createElement( 'div' );\n\t\tcontainer.appendChild( fragment );\n\n\t\treturn container.innerHTML;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/dataprocessor/basichtmlwriter.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/dataprocessor/htmldataprocessor\n */\n\n/* globals document, DOMParser */\n\nimport BasicHtmlWriter from './basichtmlwriter';\nimport DomConverter from '../view/domconverter';\nimport { NBSP_FILLER } from '../view/filler';\n\n/**\n * HtmlDataProcessor class.\n * This data processor implementation uses HTML as input/output data.\n *\n * @implements module:engine/dataprocessor/dataprocessor~DataProcessor\n */\nexport default class HtmlDataProcessor {\n\t/**\n\t * Creates a new instance of the HtmlDataProcessor class.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * DOMParser instance used to parse HTML string to HTMLDocument.\n\t\t *\n\t\t * @private\n\t\t * @member {DOMParser}\n\t\t */\n\t\tthis._domParser = new DOMParser();\n\n\t\t/**\n\t\t * DOM converter used to convert DOM elements to view elements.\n\t\t *\n\t\t * @private\n\t\t * @member\n\t\t */\n\t\tthis._domConverter = new DomConverter( { blockFiller: NBSP_FILLER } );\n\n\t\t/**\n\t\t * BasicHtmlWriter instance used to convert DOM elements to HTML string.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/dataprocessor/basichtmlwriter~BasicHtmlWriter}\n\t\t */\n\t\tthis._htmlWriter = new BasicHtmlWriter();\n\t}\n\n\t/**\n\t * Converts provided {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment}\n\t * to data format - in this case HTML string.\n\t *\n\t * @param {module:engine/view/documentfragment~DocumentFragment} viewFragment\n\t * @returns {String} HTML string.\n\t */\n\ttoData( viewFragment ) {\n\t\t// Convert view DocumentFragment to DOM DocumentFragment.\n\t\tconst domFragment = this._domConverter.viewToDom( viewFragment, document );\n\n\t\t// Convert DOM DocumentFragment to HTML output.\n\t\treturn this._htmlWriter.getHtml( domFragment );\n\t}\n\n\t/**\n\t * Converts provided HTML string to view tree.\n\t *\n\t * @param {String} data HTML string.\n\t * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null} Converted view element.\n\t */\n\ttoView( data ) {\n\t\t// Convert input HTML data to DOM DocumentFragment.\n\t\tconst domFragment = this._toDom( data );\n\n\t\t// Convert DOM DocumentFragment to view DocumentFragment.\n\t\treturn this._domConverter.domToView( domFragment );\n\t}\n\n\t/**\n\t * Converts HTML String to its DOM representation. Returns DocumentFragment, containing nodes parsed from\n\t * provided data.\n\t *\n\t * @private\n\t * @param {String} data\n\t * @returns {DocumentFragment}\n\t */\n\t_toDom( data ) {\n\t\tconst document = this._domParser.parseFromString( data, 'text/html' );\n\t\tconst fragment = document.createDocumentFragment();\n\t\tconst nodes = document.body.childNodes;\n\n\t\twhile ( nodes.length > 0 ) {\n\t\t\tfragment.appendChild( nodes[ 0 ] );\n\t\t}\n\n\t\treturn fragment;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/dataprocessor/htmldataprocessor.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) which accepts\n * {@link module:core/editor/editor~Editor the editor} as a parm.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin which enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you'll want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you'll ensure that the listener will be removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor, 'dataReady', () => {\n *\t\t\t\t\t// Do something when data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of a plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you'll want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} servers for the special \"after init\" scenarios (e.g. code which depends on other\n * plugins, but which doesn't {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep a plugin class definition tight it's recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * Optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep a plugin class definition tight it's recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/src/plugin.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/collection\n */\n\nimport EmitterMixin from './emittermixin';\nimport CKEditorError from './ckeditorerror';\nimport uid from './uid';\nimport mix from './mix';\n\n/**\n * Collections are ordered sets of objects. Items in the collection can be retrieved by their indexes\n * in the collection (like in an array) or by their ids.\n *\n * If an object without an `id` property is being added to the collection, the `id` property will be generated\n * automatically. Note that the automatically generated id is unique only within this single collection instance.\n *\n * By default an item in the collection is identified by its `id` property. The name of the identifier can be\n * configured through the constructor of the collection.\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class Collection {\n\t/**\n\t * Creates a new Collection instance.\n\t *\n\t * @param {Object} [options={}] The options object.\n\t * @param {String} [options.idProperty='id'] The name of the property which is considered to identify an item.\n\t */\n\tconstructor( options = {} ) {\n\t\t/**\n\t\t * The internal list of items in the collection.\n\t\t *\n\t\t * @private\n\t\t * @member {Object[]}\n\t\t */\n\t\tthis._items = [];\n\n\t\t/**\n\t\t * The internal map of items in the collection.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._itemMap = new Map();\n\n\t\t/**\n\t\t * The name of the property which is considered to identify an item.\n\t\t *\n\t\t * @private\n\t\t * @member {String}\n\t\t */\n\t\tthis._idProperty = options.idProperty || 'id';\n\n\t\t/**\n\t\t * A helper mapping external items of a bound collection ({@link #bindTo})\n\t\t * and actual items of this collection. It provides information\n\t\t * necessary to properly remove items bound to another collection.\n\t\t *\n\t\t * See {@link #_bindToInternalToExternalMap}.\n\t\t *\n\t\t * @protected\n\t\t * @member {WeakMap}\n\t\t */\n\t\tthis._bindToExternalToInternalMap = new WeakMap();\n\n\t\t/**\n\t\t * A helper mapping items of this collection to external items of a bound collection\n\t\t * ({@link #bindTo}). It provides information necessary to manage the bindings, e.g.\n\t\t * to avoid loops in twoway bindings.\n\t\t *\n\t\t * See {@link #_bindToExternalToInternalMap}.\n\t\t *\n\t\t * @protected\n\t\t * @member {WeakMap}\n\t\t */\n\t\tthis._bindToInternalToExternalMap = new WeakMap();\n\n\t\t/**\n\t\t * A collection instance this collection is bound to as a result\n\t\t * of calling {@link #bindTo} method.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:utils/collection~Collection} #_bindToCollection\n\t\t */\n\t}\n\n\t/**\n\t * The number of items available in the collection.\n\t *\n\t * @member {Number} #length\n\t */\n\tget length() {\n\t\treturn this._items.length;\n\t}\n\n\t/**\n\t * Returns the first item from the collection or null when collection is empty.\n\t *\n\t * @returns {Object|null} The first item or `null` if collection is empty.\n\t */\n\tget first() {\n\t\treturn this._items[ 0 ] || null;\n\t}\n\n\t/**\n\t * Returns the last item from the collection or null when collection is empty.\n\t *\n\t * @returns {Object|null} The last item or `null` if collection is empty.\n\t */\n\tget last() {\n\t\treturn this._items[ this.length - 1 ] || null;\n\t}\n\n\t/**\n\t * Adds an item into the collection.\n\t *\n\t * If the item does not have an id, then it will be automatically generated and set on the item.\n\t *\n\t * @chainable\n\t * @param {Object} item\n\t * @param {Number} [index] The position of the item in the collection. The item\n\t * is pushed to the collection when `index` not specified.\n\t * @fires add\n\t */\n\tadd( item, index ) {\n\t\tlet itemId;\n\t\tconst idProperty = this._idProperty;\n\n\t\tif ( ( idProperty in item ) ) {\n\t\t\titemId = item[ idProperty ];\n\n\t\t\tif ( typeof itemId != 'string' ) {\n\t\t\t\t/**\n\t\t\t\t * This item's id should be a string.\n\t\t\t\t *\n\t\t\t\t * @error collection-add-invalid-id\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'collection-add-invalid-id' );\n\t\t\t}\n\n\t\t\tif ( this.get( itemId ) ) {\n\t\t\t\t/**\n\t\t\t\t * This item already exists in the collection.\n\t\t\t\t *\n\t\t\t\t * @error collection-add-item-already-exists\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'collection-add-item-already-exists' );\n\t\t\t}\n\t\t} else {\n\t\t\titem[ idProperty ] = itemId = uid();\n\t\t}\n\n\t\t// TODO: Use ES6 default function argument.\n\t\tif ( index === undefined ) {\n\t\t\tindex = this._items.length;\n\t\t} else if ( index > this._items.length || index < 0 ) {\n\t\t\t/**\n\t\t\t * The index number has invalid value.\n\t\t\t *\n\t\t\t * @error collection-add-item-bad-index\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-add-item-invalid-index' );\n\t\t}\n\n\t\tthis._items.splice( index, 0, item );\n\n\t\tthis._itemMap.set( itemId, item );\n\n\t\tthis.fire( 'add', item, index );\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets item by its id or index.\n\t *\n\t * @param {String|Number} idOrIndex The item id or index in the collection.\n\t * @returns {Object|null} The requested item or `null` if such item does not exist.\n\t */\n\tget( idOrIndex ) {\n\t\tlet item;\n\n\t\tif ( typeof idOrIndex == 'string' ) {\n\t\t\titem = this._itemMap.get( idOrIndex );\n\t\t} else if ( typeof idOrIndex == 'number' ) {\n\t\t\titem = this._items[ idOrIndex ];\n\t\t} else {\n\t\t\t/**\n\t\t\t * Index or id must be given.\n\t\t\t *\n\t\t\t * @error collection-get-invalid-arg\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-get-invalid-arg: Index or id must be given.' );\n\t\t}\n\n\t\treturn item || null;\n\t}\n\n\t/**\n\t * Gets index of item in the collection.\n\t * When item is not defined in the collection then index will be equal -1.\n\t *\n\t * @param {String|Object} idOrItem The item or its id in the collection.\n\t * @returns {Number} Index of given item.\n\t */\n\tgetIndex( idOrItem ) {\n\t\tlet item;\n\n\t\tif ( typeof idOrItem == 'string' ) {\n\t\t\titem = this._itemMap.get( idOrItem );\n\t\t} else {\n\t\t\titem = idOrItem;\n\t\t}\n\n\t\treturn this._items.indexOf( item );\n\t}\n\n\t/**\n\t * Removes an item from the collection.\n\t *\n\t * @param {Object|Number|String} subject The item to remove, its id or index in the collection.\n\t * @returns {Object} The removed item.\n\t * @fires remove\n\t */\n\tremove( subject ) {\n\t\tlet index, id, item;\n\t\tlet itemDoesNotExist = false;\n\t\tconst idProperty = this._idProperty;\n\n\t\tif ( typeof subject == 'string' ) {\n\t\t\tid = subject;\n\t\t\titem = this._itemMap.get( id );\n\t\t\titemDoesNotExist = !item;\n\n\t\t\tif ( item ) {\n\t\t\t\tindex = this._items.indexOf( item );\n\t\t\t}\n\t\t} else if ( typeof subject == 'number' ) {\n\t\t\tindex = subject;\n\t\t\titem = this._items[ index ];\n\t\t\titemDoesNotExist = !item;\n\n\t\t\tif ( item ) {\n\t\t\t\tid = item[ idProperty ];\n\t\t\t}\n\t\t} else {\n\t\t\titem = subject;\n\t\t\tid = item[ idProperty ];\n\t\t\tindex = this._items.indexOf( item );\n\t\t\titemDoesNotExist = ( index == -1 || !this._itemMap.get( id ) );\n\t\t}\n\n\t\tif ( itemDoesNotExist ) {\n\t\t\t/**\n\t\t\t * Item not found.\n\t\t\t *\n\t\t\t * @error collection-remove-404\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-remove-404: Item not found.' );\n\t\t}\n\n\t\tthis._items.splice( index, 1 );\n\t\tthis._itemMap.delete( id );\n\n\t\tconst externalItem = this._bindToInternalToExternalMap.get( item );\n\t\tthis._bindToInternalToExternalMap.delete( item );\n\t\tthis._bindToExternalToInternalMap.delete( externalItem );\n\n\t\tthis.fire( 'remove', item );\n\n\t\treturn item;\n\t}\n\n\t/**\n\t * Executes the callback for each item in the collection and composes an array or values returned by this callback.\n\t *\n\t * @param {Function} callback\n\t * @param {Object} callback.item\n\t * @param {Number} callback.index\n\t * @params {Object} ctx Context in which the `callback` will be called.\n\t * @returns {Array} The result of mapping.\n\t */\n\tmap( callback, ctx ) {\n\t\treturn this._items.map( callback, ctx );\n\t}\n\n\t/**\n\t * Finds the first item in the collection for which the `callback` returns a true value.\n\t *\n\t * @param {Function} callback\n\t * @param {Object} callback.item\n\t * @param {Number} callback.index\n\t * @returns {Object} The item for which `callback` returned a true value.\n\t * @params {Object} ctx Context in which the `callback` will be called.\n\t */\n\tfind( callback, ctx ) {\n\t\treturn this._items.find( callback, ctx );\n\t}\n\n\t/**\n\t * Returns an array with items for which the `callback` returned a true value.\n\t *\n\t * @param {Function} callback\n\t * @param {Object} callback.item\n\t * @param {Number} callback.index\n\t * @params {Object} ctx Context in which the `callback` will be called.\n\t * @returns {Object[]} The array with matching items.\n\t */\n\tfilter( callback, ctx ) {\n\t\treturn this._items.filter( callback, ctx );\n\t}\n\n\t/**\n\t * Removes all items from the collection and destroys the binding created using\n\t * {@link #bindTo}.\n\t */\n\tclear() {\n\t\tif ( this._bindToCollection ) {\n\t\t\tthis.stopListening( this._bindToCollection );\n\t\t\tthis._bindToCollection = null;\n\t\t}\n\n\t\twhile ( this.length ) {\n\t\t\tthis.remove( 0 );\n\t\t}\n\t}\n\n\t/**\n\t * Binds and synchronizes the collection with another one.\n\t *\n\t * The binding can be a simple factory:\n\t *\n\t *\t\tclass FactoryClass {\n\t *\t\t\tconstructor( data ) {\n\t *\t\t\t\tthis.label = data.label;\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst source = new Collection( { idProperty: 'label' } );\n\t *\t\tconst target = new Collection();\n\t *\n\t *\t\ttarget.bindTo( source ).as( FactoryClass );\n\t *\n\t *\t\tsource.add( { label: 'foo' } );\n\t *\t\tsource.add( { label: 'bar' } );\n\t *\n\t *\t\tconsole.log( target.length ); // 2\n\t *\t\tconsole.log( target.get( 1 ).label ); // 'bar'\n\t *\n\t *\t\tsource.remove( 0 );\n\t *\t\tconsole.log( target.length ); // 1\n\t *\t\tconsole.log( target.get( 0 ).label ); // 'bar'\n\t *\n\t * or the factory driven by a custom callback:\n\t *\n\t *\t\tclass FooClass {\n\t *\t\t\tconstructor( data ) {\n\t *\t\t\t\tthis.label = data.label;\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tclass BarClass {\n\t *\t\t\tconstructor( data ) {\n\t *\t\t\t\tthis.label = data.label;\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst source = new Collection( { idProperty: 'label' } );\n\t *\t\tconst target = new Collection();\n\t *\n\t *\t\ttarget.bindTo( source ).using( ( item ) => {\n\t *\t\t\tif ( item.label == 'foo' ) {\n\t *\t\t\t\treturn new FooClass( item );\n\t *\t\t\t} else {\n\t *\t\t\t\treturn new BarClass( item );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\tsource.add( { label: 'foo' } );\n\t *\t\tsource.add( { label: 'bar' } );\n\t *\n\t *\t\tconsole.log( target.length ); // 2\n\t *\t\tconsole.log( target.get( 0 ) instanceof FooClass ); // true\n\t *\t\tconsole.log( target.get( 1 ) instanceof BarClass ); // true\n\t *\n\t * or the factory out of property name:\n\t *\n\t *\t\tconst source = new Collection( { idProperty: 'label' } );\n\t *\t\tconst target = new Collection();\n\t *\n\t *\t\ttarget.bindTo( source ).using( 'label' );\n\t *\n\t *\t\tsource.add( { label: { value: 'foo' } } );\n\t *\t\tsource.add( { label: { value: 'bar' } } );\n\t *\n\t *\t\tconsole.log( target.length ); // 2\n\t *\t\tconsole.log( target.get( 0 ).value ); // 'foo'\n\t *\t\tconsole.log( target.get( 1 ).value ); // 'bar'\n\t *\n\t * **Note**: {@link #clear} can be used to break the binding.\n\t *\n\t * @param {module:utils/collection~Collection} collection A collection to be bound.\n\t * @returns {Object}\n\t * @returns {module:utils/collection~Collection#bindTo#as} return.as\n\t * @returns {module:utils/collection~Collection#bindTo#using} return.using\n\t */\n\tbindTo( externalCollection ) {\n\t\tif ( this._bindToCollection ) {\n\t\t\t/**\n\t\t\t * The collection cannot be bound more than once.\n\t\t\t *\n\t\t\t * @error collection-bind-to-rebind\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-bind-to-rebind: The collection cannot be bound more than once.' );\n\t\t}\n\n\t\tthis._bindToCollection = externalCollection;\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * Creates the class factory binding.\n\t\t\t *\n\t\t\t * @static\n\t\t\t * @param {Function} Class Specifies which class factory is to be initialized.\n\t\t\t */\n\t\t\tas: Class => {\n\t\t\t\tthis._setUpBindToBinding( item => new Class( item ) );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Creates callback or property binding.\n\t\t\t *\n\t\t\t * @static\n\t\t\t * @param {Function|String} callbackOrProperty When the function is passed, it is used to\n\t\t\t * produce the items. When the string is provided, the property value is used to create\n\t\t\t * the bound collection items.\n\t\t\t */\n\t\t\tusing: callbackOrProperty => {\n\t\t\t\tif ( typeof callbackOrProperty == 'function' ) {\n\t\t\t\t\tthis._setUpBindToBinding( item => callbackOrProperty( item ) );\n\t\t\t\t} else {\n\t\t\t\t\tthis._setUpBindToBinding( item => item[ callbackOrProperty ] );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Finalizes and activates a binding initiated by {#bindTo}.\n\t *\n\t * @protected\n\t * @param {Function} factory A function which produces collection items.\n\t */\n\t_setUpBindToBinding( factory ) {\n\t\tconst externalCollection = this._bindToCollection;\n\n\t\t// Adds the item to the collection once a change has been done to the external collection.\n\t\t//\n\t\t// @private\n\t\tconst addItem = ( evt, externalItem, index ) => {\n\t\t\tconst isExternalBoundToThis = externalCollection._bindToCollection == this;\n\t\t\tconst externalItemBound = externalCollection._bindToInternalToExternalMap.get( externalItem );\n\n\t\t\t// If an external collection is bound to this collection, which makes it a 2way binding,\n\t\t\t// and the particular external collection item is already bound, don't add it here.\n\t\t\t// The external item has been created **out of this collection's item** and (re)adding it will\n\t\t\t// cause a loop.\n\t\t\tif ( isExternalBoundToThis && externalItemBound ) {\n\t\t\t\tthis._bindToExternalToInternalMap.set( externalItem, externalItemBound );\n\t\t\t\tthis._bindToInternalToExternalMap.set( externalItemBound, externalItem );\n\t\t\t} else {\n\t\t\t\tconst item = factory( externalItem );\n\n\t\t\t\tthis._bindToExternalToInternalMap.set( externalItem, item );\n\t\t\t\tthis._bindToInternalToExternalMap.set( item, externalItem );\n\n\t\t\t\tthis.add( item, index );\n\t\t\t}\n\t\t};\n\n\t\t// Load the initial content of the collection.\n\t\tfor ( const externalItem of externalCollection ) {\n\t\t\taddItem( null, externalItem );\n\t\t}\n\n\t\t// Synchronize the with collection as new items are added.\n\t\tthis.listenTo( externalCollection, 'add', addItem );\n\n\t\t// Synchronize the with collection as new items are removed.\n\t\tthis.listenTo( externalCollection, 'remove', ( evt, externalItem ) => {\n\t\t\tconst item = this._bindToExternalToInternalMap.get( externalItem );\n\n\t\t\tif ( item ) {\n\t\t\t\tthis.remove( item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Collection iterator.\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._items[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Fired when an item is added to the collection.\n\t *\n\t * @event add\n\t * @param {Object} item The added item.\n\t */\n\n\t/**\n\t * Fired when an item is removed from the collection.\n\t *\n\t * @event remove\n\t * @param {Object} item The removed item.\n\t */\n}\n\nmix( Collection, EmitterMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/collection.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* global setTimeout, clearTimeout */\n\n/**\n * @module utils/focustracker\n */\n\nimport DomEmitterMixin from './dom/emittermixin';\nimport ObservableMixin from './observablemixin';\nimport CKEditorError from './ckeditorerror';\nimport mix from './mix';\n\n/**\n * Allows observing a group of `HTMLElement`s whether at least one of them is focused.\n *\n * Used by the {@link module:core/editor/editor~Editor} in order to track whether the focus is still within the application,\n * or were used outside of its UI.\n *\n * **Note** `focus` and `blur` listeners use event capturing, so it is only needed to register wrapper `HTMLElement`\n * which contain other `focusable` elements. But note that this wrapper element has to be focusable too\n * (have e.g. `tabindex=\"-1\"`).\n *\n * @mixes module:utils/dom/emittermixin~EmitterMixin\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class FocusTracker {\n\tconstructor() {\n\t\t/**\n\t\t * True when one of the registered elements is focused.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #isFocused\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * Currently focused element.\n\t\t *\n\t\t * @readonly\n\t\t * @member {HTMLElement}\n\t\t */\n\t\tthis.focusedElement = null;\n\n\t\t/**\n\t\t * List of registered elements.\n\t\t *\n\t\t * @private\n\t\t * @member {Set.<HTMLElement>}\n\t\t */\n\t\tthis._elements = new Set();\n\n\t\t/**\n\t\t * Event loop timeout.\n\t\t *\n\t\t * @private\n\t\t * @member {Number}\n\t\t */\n\t\tthis._nextEventLoopTimeout = null;\n\t}\n\n\t/**\n\t * Starts tracking the specified element.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tadd( element ) {\n\t\tif ( this._elements.has( element ) ) {\n\t\t\tthrow new CKEditorError( 'focusTracker-add-element-already-exist' );\n\t\t}\n\n\t\tthis.listenTo( element, 'focus', () => this._focus( element ), { useCapture: true } );\n\t\tthis.listenTo( element, 'blur', () => this._blur(), { useCapture: true } );\n\t\tthis._elements.add( element );\n\t}\n\n\t/**\n\t * Stops tracking the specified element and stops listening on this element.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tremove( element ) {\n\t\tif ( element === this.focusedElement ) {\n\t\t\tthis._blur( element );\n\t\t}\n\n\t\tif ( this._elements.has( element ) ) {\n\t\t\tthis.stopListening( element );\n\t\t\tthis._elements.delete( element );\n\t\t}\n\t}\n\n\t/**\n\t * Stores currently focused element and set {#isFocused} as `true`.\n\t *\n\t * @private\n\t * @param {HTMLElement} element Element which has been focused.\n\t */\n\t_focus( element ) {\n\t\tclearTimeout( this._nextEventLoopTimeout );\n\n\t\tthis.focusedElement = element;\n\t\tthis.isFocused = true;\n\t}\n\n\t/**\n\t * Clears currently focused element and set {@link #isFocused} as `false`.\n\t * This method uses `setTimeout` to change order of fires `blur` and `focus` events.\n\t *\n\t * @private\n\t * @fires blur\n\t */\n\t_blur() {\n\t\tclearTimeout( this._nextEventLoopTimeout );\n\n\t\tthis._nextEventLoopTimeout = setTimeout( () => {\n\t\t\tthis.focusedElement = null;\n\t\t\tthis.isFocused = false;\n\t\t}, 0 );\n\t}\n\n\t/**\n\t * @event focus\n\t */\n\n\t/**\n\t * @event blur\n\t */\n}\n\nmix( FocusTracker, DomEmitterMixin );\nmix( FocusTracker, ObservableMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/focustracker.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/editorui/editoruiview\n */\n\n/* globals document */\n\nimport View from '../view';\nimport Template from '../template';\n\n/**\n * The editor UI view class. Base class for the editor main views.\n *\n * @extends module:ui/view~View\n */\nexport default class EditorUIView extends View {\n\t/**\n\t * Creates an instance of the editor UI view class.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The locale instance.\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * Collection of the child views, detached from the DOM\n\t\t * structure of the editor, like panels, icons etc.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection} #body\n\t\t */\n\t\tthis.body = this.createCollection();\n\n\t\t/**\n\t\t * The element holding elements of the 'body' region.\n\t\t *\n\t\t * @private\n\t\t * @member {HTMLElement} #_bodyCollectionContainer\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis._renderBodyCollection();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis._bodyCollectionContainer.remove();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * Creates and appends to `<body>` the {@link #body} collection container.\n\t *\n\t * @private\n\t */\n\t_renderBodyCollection() {\n\t\tconst bodyElement = this._bodyCollectionContainer = new Template( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-body',\n\t\t\t\t\t'ck-rounded-corners',\n\t\t\t\t\t'ck-reset_all'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.body\n\t\t} ).render();\n\n\t\tdocument.body.appendChild( bodyElement );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/editorui/editoruiview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/editableui/editableuiview\n */\n\nimport View from '../view';\n\n/**\n * The editable UI view class.\n *\n * @extends module:ui/view~View\n */\nexport default class EditableUIView extends View {\n\t/**\n\t * Creates an instance of EditableUIView class.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The locale instance.\n\t * @param {HTMLElement} [editableElement] The editable element. If not specified, this view\n\t * should create it. Otherwise, the existing element should be used.\n\t */\n\tconstructor( locale, editableElement ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tif ( editableElement ) {\n\t\t\tthis.element = this.editableElement = editableElement;\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\tbind.to( 'isFocused', value => value ? 'ck-focused' : 'ck-blurred' ),\n\t\t\t\t\t'ck-editor__editable',\n\t\t\t\t\t'ck-rounded-corners'\n\t\t\t\t],\n\t\t\t\tcontenteditable: bind.to( 'isReadOnly', value => !value ),\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Controls whether the editable is writable or not.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * Controls whether the editable is focused, i.e. the user is typing in it.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isFocused\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * An external {@link #editableElement} passed into the constructor, which also means\n\t\t * the view will not render its {@link #template}.\n\t\t *\n\t\t * @member {HTMLElement} #externalElement\n\t\t */\n\t\tthis.externalElement = editableElement;\n\n\t\t/**\n\t\t * The element which is the main editable element (usually the one with `contentEditable=\"true\"`).\n\t\t *\n\t\t * @readonly\n\t\t * @member {HTMLElement} #editableElement\n\t\t */\n\t}\n\n\t/**\n\t * Renders the view by either applying the {@link #template} to the existing\n\t * {@link #editableElement} or assigning {@link #element} as {@link #editableElement}.\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tif ( this.externalElement ) {\n\t\t\tthis.template.apply( this.element = this.externalElement );\n\t\t} else {\n\t\t\tthis.editableElement = this.element;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tif ( this.externalElement ) {\n\t\t\tthis.template.revert( this.externalElement );\n\t\t}\n\n\t\tsuper.destroy();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/editableui/editableuiview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module ui/editableui/inline/inlineeditableuiview\n */\nimport EditableUIView from '../../editableui/editableuiview';\n/**\n * The inline editable UI class implementing an inline {@link module:ui/editableui/editableuiview~EditableUIView}.\n *\n * @extends module:ui/editableui/editableuiview~EditableUIView\n */\nexport default class InlineEditableUIView extends EditableUIView {\n /**\n\t * Creates an instance of the InlineEditableUIView class.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The locale instance.\n\t * @param {HTMLElement} [editableElement] The editable element. If not specified, the\n\t * {@link module:ui/editableui/editableuiview~EditableUIView}\n\t * should create it. Otherwise, the existing element should be used.\n\t */\n constructor(locale, editableElement) {\n super(locale, editableElement);\n const bind = this.bindTemplate;\n const t = this.t;\n /**\n\t\t * The name of the editable UI view.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #name\n\t\t */\n this.set('name', null);\n const getLabel = value => {\n return t('Rich Text Editor, %0', [value]);\n };\n this.extendTemplate({\n attributes: {\n role: 'textbox',\n 'aria-label': bind.to('name', getLabel),\n class: 'ck-editor__editable_inline'\n }\n });\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/editableui/inline/inlineeditableuiview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module editor-balloon/ballooneditoruiview\n */\n\nimport EditorUIView from '@ckeditor/ckeditor5-ui/src/editorui/editoruiview';\nimport InlineEditableUIView from '@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview';\n\n/**\n * Contextual editor UI view. Uses the {@link module:ui/editableui/inline/inlineeditableuiview~InlineEditableUIView}.\n *\n * @extends module:ui/editorui/editoruiview~EditorUIView\n */\nexport default class BalloonEditorUIView extends EditorUIView {\n\t/**\n\t * Creates an instance of the balloon editor UI view.\n\t *\n\t * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t */\n\tconstructor( locale, editableElement ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The editable UI view.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/editableui/inline/inlineeditableuiview~InlineEditableUIView}\n\t\t */\n\t\tthis.editable = new InlineEditableUIView( locale, editableElement );\n\n\t\tthis.registerChildren( this.editable );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget editableElement() {\n\t\treturn this.editable.element;\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-editor-balloon/src/ballooneditoruiview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module editor-balloon/ballooneditor\n */\n\nimport StandardEditor from '@ckeditor/ckeditor5-core/src/editor/standardeditor';\nimport HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';\nimport ContextualToolbar from '@ckeditor/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar';\nimport BalloonEditorUI from './ballooneditorui';\nimport BalloonEditorUIView from './ballooneditoruiview';\nimport setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement';\n\nimport '../theme/theme.scss';\n\n/**\n * The {@glink builds/guides/overview#Balloon-editor balloon editor} implementation (Medium-like editor).\n * It uses an inline editable and a toolbar based on the {@link module:ui/toolbar/contextual/contextualtoolbar~ContextualToolbar}.\n * See the {@glink examples/builds/balloon-editor demo}.\n *\n * In order to create a balloon editor instance, use the static\n * {@link module:editor-balloon/ballooneditor~BalloonEditor#create `BalloonEditor.create()`} method.\n *\n * # Balloon editor and balloon build\n *\n * The balloon editor can be used directly from source (if you installed the\n * [`@ckeditor/ckeditor5-editor-balloon`](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon) package)\n * but it is also available in the {@glink builds/guides/overview#Balloon-editor balloon build}.\n *\n * {@glink builds/guides/overview Builds} are ready-to-use editors with plugins bundled in. When using the editor from\n * source you need to take care of loading all plugins by yourself\n * (through the {@link module:core/editor/editorconfig~EditorConfig#plugins `config.plugins`} option).\n * Using the editor from source gives much better flexibility and allows easier customization.\n *\n * Read more about initializing the editor from source or as a build in\n * {@link module:editor-balloon/ballooneditor~BalloonEditor#create `BalloonEditor.create()`}.\n *\n * @extends module:core/editor/standardeditor~StandardEditor\n */\nexport default class BalloonEditor extends StandardEditor {\n\t/**\n\t * Creates an instance of the balloon editor.\n\t *\n\t * **Note:** do not use the constructor to create editor instances. Use the static\n\t * {@link module:editor-balloon/ballooneditor~BalloonEditor#create `BalloonEditor.create()`} method instead.\n\t *\n\t * @protected\n\t * @param {HTMLElement} element The DOM element that will be the source for the created editor\n\t * (on which the editor will be initialized).\n\t * @param {module:core/editor/editorconfig~EditorConfig} config The editor configuration.\n\t */\n\tconstructor( element, config ) {\n\t\tsuper( element, config );\n\n\t\tthis.config.get( 'plugins' ).push( ContextualToolbar );\n\t\tthis.config.define( 'contextualToolbar', this.config.get( 'toolbar' ) );\n\n\t\tthis.document.createRoot();\n\t\tthis.data.processor = new HtmlDataProcessor();\n\t\tthis.ui = new BalloonEditorUI( this, new BalloonEditorUIView( this.locale, element ) );\n\t}\n\n\t/**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * Updates the original editor element with the data.\n\t *\n\t * @returns {Promise}\n\t */\n\tdestroy() {\n\t\t// Cache the data, then destroy.\n\t\t// It's safe to assume that the model->view conversion will not work after super.destroy().\n\t\tconst data = this.getData();\n\n\t\tthis.ui.destroy();\n\n\t\treturn super.destroy()\n\t\t\t.then( () => setDataInElement( this.element, data ) );\n\t}\n\n\t/**\n\t * Creates a balloon editor instance.\n\t *\n\t * Creating instance when using {@glink builds/index CKEditor build}:\n\t *\n\t *\t\tBalloonEditor\n\t *\t\t\t.create( document.querySelector( '#editor' ) )\n\t *\t\t\t.then( editor => {\n\t *\t\t\t\tconsole.log( 'Editor was initialized', editor );\n\t *\t\t\t} )\n\t *\t\t\t.catch( err => {\n\t *\t\t\t\tconsole.error( err.stack );\n\t *\t\t\t} );\n\t *\n\t * Creating instance when using CKEditor from source (make sure to specify the list of plugins to load and the toolbar):\n\t *\n\t *\t\timport BalloonEditor from '@ckeditor/ckeditor5-editor-balloon/src/ballooneditor';\n\t *\t\timport Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';\n\t *\t\timport Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';\n\t *\t\timport Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';\n\t *\t\timport ...\n\t *\n\t *\t\tBalloonEditor\n\t *\t\t\t.create( document.querySelector( '#editor' ), {\n\t *\t\t\t\tplugins: [ Essentials, Bold, Italic, ... ],\n\t *\t\t\t\ttoolbar: [ 'bold', 'italic', ... ]\n\t *\t\t\t} )\n\t *\t\t\t.then( editor => {\n\t *\t\t\t\tconsole.log( 'Editor was initialized', editor );\n\t *\t\t\t} )\n\t *\t\t\t.catch( err => {\n\t *\t\t\t\tconsole.error( err.stack );\n\t *\t\t\t} );\n\t *\n\t * @param {HTMLElement} element The DOM element that will be the source for the created editor\n\t * (on which the editor will be initialized).\n\t * @param {module:core/editor/editorconfig~EditorConfig} config The editor configuration.\n\t * @returns {Promise} A promise resolved once the editor is ready.\n\t * The promise returns the created {@link module:editor-balloon/ballooneditor~BalloonEditor} instance.\n\t */\n\tstatic create( element, config ) {\n\t\treturn new Promise( resolve => {\n\t\t\tconst editor = new this( element, config );\n\n\t\t\tresolve(\n\t\t\t\teditor.initPlugins()\n\t\t\t\t\t.then( () => {\n\t\t\t\t\t\teditor.ui.init();\n\t\t\t\t\t\teditor.fire( 'uiReady' );\n\t\t\t\t\t} )\n\t\t\t\t\t.then( () => editor.loadDataFromEditorElement() )\n\t\t\t\t\t.then( () => {\n\t\t\t\t\t\teditor.fire( 'dataReady' );\n\t\t\t\t\t\teditor.fire( 'ready' );\n\t\t\t\t\t} )\n\t\t\t\t\t.then( () => editor )\n\t\t\t);\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-editor-balloon/src/ballooneditor.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of a command. Concrete command class should define what it represents.\n\t\t *\n\t\t * For example, the `bold` command's value is whether the selection starts in a bolded text.\n\t\t * And the value of the `link` command may be an object with links details.\n\t\t *\n\t\t * It's possible for a command to have no value (e.g. for stateless actions such as `uploadImage`).\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command should do nothing when executed.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.document, 'changesDone', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\t// See a ticket about overriding observable properties\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-utils/issues/171.\n\t\t\t\tthis.on( 'change:isEnabled', forceDisable, { priority: 'lowest' } );\n\t\t\t\tthis.isEnabled = false;\n\t\t\t} else {\n\t\t\t\tthis.off( 'change:isEnabled', forceDisable );\n\t\t\t\tthis.refresh();\n\t\t\t}\n\t\t} );\n\n\t\tfunction forceDisable() {\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} property\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:changesDone any changes are applied to the model}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin.decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/src/command.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module enter/enter\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport EnterCommand from './entercommand';\nimport EnterObserver from './enterobserver';\n\n/**\n * The Enter feature. Handles the <kbd>Enter</kbd> and <kbd>Shift + Enter</kbd> keys in the editor.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Enter extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Enter';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\n\t\teditingView.addObserver( EnterObserver );\n\n\t\teditor.commands.add( 'enter', new EnterCommand( editor ) );\n\n\t\t// TODO We may use the keystroke handler for that.\n\t\tthis.listenTo( editingView, 'enter', ( evt, data ) => {\n\t\t\teditor.execute( 'enter' );\n\t\t\tdata.preventDefault();\n\t\t\teditingView.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-enter/src/enter.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/inputcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport ChangeBuffer from './changebuffer';\n\n/**\n * The input command. Used by the {@link module:typing/input~Input input feature} to handle typing.\n *\n * @extends module:core/command~Command\n */\nexport default class InputCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {Number} undoStepSize The maximum number of atomic changes\n\t * which can be contained in one batch in the command buffer.\n\t */\n\tconstructor( editor, undoStepSize ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Typing's change buffer used to group subsequent changes into batches.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {module:typing/changebuffer~ChangeBuffer} #_buffer\n\t\t */\n\t\tthis._buffer = new ChangeBuffer( editor.document, undoStepSize );\n\t}\n\n\t/**\n\t * The current change buffer.\n\t *\n\t * @type {module:typing/changebuffer~ChangeBuffer}\n\t */\n\tget buffer() {\n\t\treturn this._buffer;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tthis._buffer.destroy();\n\t}\n\n\t/**\n\t * Executes the input command. It replaces the content within the given range with the given text.\n\t * Replacing is a two step process, first the content within the range is removed and then the new text is inserted\n\t * at the beginning of the range (which after the removal is a collapsed range).\n\t *\n\t * @fires execute\n\t * @param {Object} [options] The command options.\n\t * @param {String} [options.text=''] The text to be inserted.\n\t * @param {module:engine/model/range~Range} [options.range] The range in which the text is inserted. Defaults\n\t * to the first range in the current selection.\n\t * @param {module:engine/model/range~Range} [options.resultRange] The range where the selection\n\t * should be placed after the insertion. If not specified, the selection will be placed right after\n\t * the inserted text.\n\t */\n\texecute( options = {} ) {\n\t\tconst doc = this.editor.document;\n\t\tconst text = options.text || '';\n\t\tconst textInsertions = text.length;\n\t\tconst range = options.range || doc.selection.getFirstRange();\n\t\tconst resultRange = options.resultRange;\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tconst isCollapsedRange = range.isCollapsed;\n\n\t\t\tthis._buffer.lock();\n\n\t\t\tif ( !isCollapsedRange ) {\n\t\t\t\tthis._buffer.batch.remove( range );\n\t\t\t}\n\n\t\t\tif ( text ) {\n\t\t\t\tthis._buffer.batch.weakInsert( range.start, text );\n\t\t\t}\n\n\t\t\tif ( resultRange ) {\n\t\t\t\tthis.editor.data.model.selection.setRanges( [ resultRange ] );\n\t\t\t} else if ( isCollapsedRange ) {\n\t\t\t\t// If range was collapsed just shift the selection by the number of inserted characters.\n\t\t\t\tthis.editor.data.model.selection.setCollapsedAt( range.start.getShiftedBy( textInsertions ) );\n\t\t\t}\n\n\t\t\tthis._buffer.unlock();\n\n\t\t\tthis._buffer.input( textInsertions );\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-typing/src/inputcommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/deleteobserver\n */\n\nimport Observer from '@ckeditor/ckeditor5-engine/src/view/observer/observer';\nimport DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * Delete observer introduces the {@link module:engine/view/document~Document#event:delete} event.\n *\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class DeleteObserver extends Observer {\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\tlet sequence = 0;\n\n\t\tdocument.on( 'keyup', ( evt, data ) => {\n\t\t\tif ( data.keyCode == keyCodes.delete || data.keyCode == keyCodes.backspace ) {\n\t\t\t\tsequence = 0;\n\t\t\t}\n\t\t} );\n\n\t\tdocument.on( 'keydown', ( evt, data ) => {\n\t\t\tconst deleteData = {};\n\n\t\t\tif ( data.keyCode == keyCodes.delete ) {\n\t\t\t\tdeleteData.direction = 'forward';\n\t\t\t\tdeleteData.unit = 'character';\n\t\t\t} else if ( data.keyCode == keyCodes.backspace ) {\n\t\t\t\tdeleteData.direction = 'backward';\n\t\t\t\tdeleteData.unit = 'codePoint';\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdeleteData.unit = data.altKey ? 'word' : deleteData.unit;\n\t\t\tdeleteData.sequence = ++sequence;\n\n\t\t\tdocument.fire( 'delete', new DomEventData( document, data.domEvent, deleteData ) );\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve() {}\n}\n\n/**\n * Event fired when the user tries to delete content (e.g. presses <kbd>Delete</kbd> or <kbd>Backspace</kbd>).\n *\n * Note: This event is fired by the {@link module:typing/deleteobserver~DeleteObserver observer}\n * (usually registered by the {@link module:typing/delete~Delete delete feature}).\n *\n * @event module:engine/view/document~Document#event:delete\n * @param {module:engine/view/observer/domeventdata~DomEventData} data\n * @param {'forward'|'delete'} data.direction The direction in which the deletion should happen.\n * @param {'character'|'word'} data.unit The \"amount\" of content that should be deleted.\n * @param {Number} data.sequence A number describing which subsequent delete event it is without the key being released.\n * If it's 2 or more it means that the key was pressed and hold.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-typing/src/deleteobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/delete\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport DeleteCommand from './deletecommand';\nimport DeleteObserver from './deleteobserver';\n\n/**\n * The delete and backspace feature. Handles the <kbd>Delete</kbd> and <kbd>Backspace</kbd> keys in the editor.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Delete extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Delete';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\n\t\teditingView.addObserver( DeleteObserver );\n\n\t\teditor.commands.add( 'forwardDelete', new DeleteCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'delete', new DeleteCommand( editor, 'backward' ) );\n\n\t\tthis.listenTo( editingView, 'delete', ( evt, data ) => {\n\t\t\teditor.execute( data.direction == 'forward' ? 'forwardDelete' : 'delete', { unit: data.unit, sequence: data.sequence } );\n\t\t\tdata.preventDefault();\n\t\t\teditingView.scrollToTheSelection();\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-typing/src/delete.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/typing\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Input from './input';\nimport Delete from './delete';\n\n/**\n * The typing feature. It handles typing.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Typing extends Plugin {\n\tstatic get requires() {\n\t\treturn [ Input, Delete ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Typing';\n\t}\n}\n\n/**\n * The configuration of the typing features. Used by the features from the `@ckeditor/ckeditor5-typing` package.\n *\n * Read more in {@link module:typing/typing~TypingConfig}.\n *\n * @member {module:typing/typing~TypingConfig} module:core/editor/editorconfig~EditorConfig#typing\n */\n\n/**\n * The configuration of the typing features. Used by the typing features in `@ckeditor/ckeditor5-typing` package.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\ttyping: ... // Typing feature options.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface TypingConfig\n */\n\n/**\n * The granularity of undo/redo for typing and deleting. The value `20` means (more or less) that a new undo step\n * is created every 20 characters are inserted or deleted.\n *\n * @member {Number} [module:typing/typing~TypingConfig#undoStep=20]\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-typing/src/typing.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/redocommand\n */\n\nimport BaseCommand from './basecommand';\n\n/**\n * The redo command stores {@link module:engine/model/batch~Batch batches} that were used to undo a batch by\n * {@link module:undo/undocommand~UndoCommand}. It is able to redo a previously undone batch by reversing the undoing\n * batches created by `UndoCommand`. The reversed batch is transformed by all the batches from\n * {@link module:engine/model/document~Document#history history} that happened after the reversed undo batch.\n *\n * The redo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.\n *\n * @extends module:undo/basecommand~BaseCommand\n */\nexport default class RedoCommand extends BaseCommand {\n\t/**\n\t * Executes the command. This method reverts the last {@link module:engine/model/batch~Batch batch} added to\n\t * the command's stack, applies the reverted and transformed version on the\n\t * {@link module:engine/model/document~Document document} and removes the batch from the stack.\n\t * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst item = this._stack.pop();\n\n\t\t// All changes have to be done in one `enqueueChanges` callback so other listeners will not\n\t\t// step between consecutive deltas, or won't do changes to the document before selection is properly restored.\n\t\tthis.editor.document.enqueueChanges( () => {\n\t\t\tconst lastDelta = item.batch.deltas[ item.batch.deltas.length - 1 ];\n\t\t\tconst nextBaseVersion = lastDelta.baseVersion + lastDelta.operations.length;\n\t\t\tconst deltas = this.editor.document.history.getDeltas( nextBaseVersion );\n\n\t\t\tthis._restoreSelection( item.selection.ranges, item.selection.isBackward, deltas );\n\t\t\tthis._undo( item.batch );\n\t\t} );\n\n\t\tthis.refresh();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-undo/src/redocommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/undoengine\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport UndoCommand from './undocommand';\nimport RedoCommand from './redocommand';\n\n/**\n * The undo engine feature.\n *\n * Undo brings in possibility to undo and redo changes done in the model by deltas through\n * the {@link module:engine/model/document~Document#batch Batch API}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class UndoEngine extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The command that manages undo {@link module:engine/model/batch~Batch batches} stack (history).\n\t\t * Created and registered during the {@link #init feature initialization}.\n\t\t *\n\t\t * @private\n\t\t * @member {undo.UndoEngineCommand} #_undoCommand\n\t\t */\n\n\t\t/**\n\t\t * The command that manages redo {@link module:engine/model/batch~Batch batches} stack (history).\n\t\t * Created and registered during the {@link #init feature initialization}.\n\t\t *\n\t\t * @private\n\t\t * @member {undo.UndoEngineCommand} #_redoCommand\n\t\t */\n\n\t\t/**\n\t\t * Keeps track of which batches were registered in undo.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakSet.<module:engine/model/batch~Batch>}\n\t\t */\n\t\tthis._batchRegistry = new WeakSet();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\t// Create commands.\n\t\tthis._undoCommand = new UndoCommand( this.editor );\n\t\tthis._redoCommand = new RedoCommand( this.editor );\n\n\t\t// Register command to the editor.\n\t\tthis.editor.commands.add( 'undo', this._undoCommand );\n\t\tthis.editor.commands.add( 'redo', this._redoCommand );\n\n\t\tthis.listenTo( this.editor.document, 'change', ( evt, type, changes, batch ) => {\n\t\t\t// If changes are not a part of a batch or this is not a new batch, omit those changes.\n\t\t\tif ( this._batchRegistry.has( batch ) || batch.type == 'transparent' ) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tif ( this._redoCommand._createdBatches.has( batch ) ) {\n\t\t\t\t\t// If this batch comes from `redoCommand`, add it to `undoCommand` stack.\n\t\t\t\t\tthis._undoCommand.addBatch( batch );\n\t\t\t\t} else if ( !this._undoCommand._createdBatches.has( batch ) ) {\n\t\t\t\t\t// A default batch - these are new changes in the document, not introduced by undo feature.\n\t\t\t\t\t// Add them to `undoCommand` stack and clear `redoCommand` stack.\n\t\t\t\t\tthis._undoCommand.addBatch( batch );\n\t\t\t\t\tthis._redoCommand.clearStack();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add the batch to the registry so it will not be processed again.\n\t\t\tthis._batchRegistry.add( batch );\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.listenTo( this._undoCommand, 'revert', ( evt, undoneBatch, undoingBatch ) => {\n\t\t\tthis._redoCommand.addBatch( undoingBatch );\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-undo/src/undoengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* global DOMParser */\n\n/**\n * @module ui/icon/iconview\n */\n\nimport View from '../view';\n\n/**\n * The icon view class.\n *\n * @extends module:ui/view~View\n */\nexport default class IconView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * The SVG source of the icon.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #content\n\t\t */\n\t\tthis.set( 'content', '' );\n\n\t\t/**\n\t\t * This attribute specifies the boundaries to which the\n\t\t * icon content should stretch.\n\t\t *\n\t\t * @observable\n\t\t * @default '0 0 20 20'\n\t\t * @member {String} #viewBox\n\t\t */\n\t\tthis.set( 'viewBox', '0 0 20 20' );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'svg',\n\t\t\tns: 'http://www.w3.org/2000/svg',\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-icon',\n\t\t\t\tviewBox: bind.to( 'viewBox' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis._updateXMLContent();\n\n\t\t// This is a hack for lack of innerHTML binding.\n\t\t// See: https://github.com/ckeditor/ckeditor5-ui/issues/99.\n\t\tthis.on( 'change:content', () => this._updateXMLContent() );\n\t}\n\n\t/**\n\t * Updates the {@link #element} with the value of {@link #content}.\n\t *\n\t * @private\n\t */\n\t_updateXMLContent() {\n\t\tif ( this.content ) {\n\t\t\tconst svg = new DOMParser()\n\t\t\t\t.parseFromString( this.content.trim(), 'image/svg+xml' )\n\t\t\t\t.firstChild;\n\n\t\t\tthis.element.innerHTML = '';\n\n\t\t\twhile ( svg.childNodes.length > 0 ) {\n\t\t\t\tthis.element.appendChild( svg.childNodes[ 0 ] );\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/icon/iconview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/tooltip/tooltipview\n */\n\nimport View from '../view';\n\n/**\n * The tooltip view class.\n *\n * @extends module:ui/view~View\n */\nexport default class TooltipView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The text of the tooltip visible to the user.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #text\n\t\t */\n\t\tthis.set( 'text', '' );\n\n\t\t/**\n\t\t * The position of the tooltip (south or north).\n\t\t *\n\t\t *\t\t+-----------+\n\t\t *\t\t| north |\n\t\t *\t\t+-----------+\n\t\t *\t\t V\n\t\t *\t\t [element]\n\t\t *\n\t\t *\t\t [element]\n\t\t *\t\t ^\n\t\t *\t\t+-----------+\n\t\t *\t\t| south |\n\t\t *\t\t+-----------+\n\t\t *\n\t\t * @observable\n\t\t * @default 's'\n\t\t * @member {'s'|'n'} #position\n\t\t */\n\t\tthis.set( 'position', 's' );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-tooltip',\n\t\t\t\t\tbind.to( 'position', position => 'ck-tooltip_' + position ),\n\t\t\t\t\tbind.if( 'text', 'ck-hidden', value => !value.trim() )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck-tooltip__text'\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttext: bind.to( 'text' ),\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} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/tooltip/tooltipview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/button/buttonview\n */\n\nimport View from '../view';\nimport IconView from '../icon/iconview';\nimport TooltipView from '../tooltip/tooltipview';\n\nimport { getEnvKeystrokeText } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * The button view class.\n *\n *\t\tconst view = new ButtonView();\n *\n *\t\tview.set( {\n *\t\t\tlabel: 'A button',\n *\t\t\tkeystroke: 'Ctrl+B',\n *\t\t\ttooltip: true,\n *\t\t\twithText: true\n *\t\t} );\n *\n *\t\tview.render();\n *\n *\t\tdocument.body.append( view.element );\n *\n * @extends module:ui/view~View\n */\nexport default class ButtonView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * The label of the button view visible to the user when {@link #withText} is `true`.\n\t\t * It can also be used to create a {@link #tooltip}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #label\n\t\t */\n\t\tthis.set( 'label' );\n\n\t\t/**\n\t\t * (Optional) The keystroke associated with the button, i.e. <kbd>CTRL+B</kbd>,\n\t\t * in the string format compatible with {@link module:utils/keyboard}.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #keystroke\n\t\t */\n\t\tthis.set( 'keystroke' );\n\n\t\t/**\n\t\t * (Optional) Tooltip of the button, i.e. displayed when hovering the button with the mouse cursor.\n\t\t *\n\t\t * * If defined as a `Boolean` (e.g. `true`), then combination of `label` and `keystroke` will be set as a tooltip.\n\t\t * * If defined as a `String`, tooltip will equal the exact text of that `String`.\n\t\t * * If defined as a `Function`, `label` and `keystroke` will be passed to that function, which is to return\n\t\t * a string with the tooltip text.\n\t\t *\n\t\t *\t\tconst view = new ButtonView( locale );\n\t\t *\t\tview.tooltip = ( label, keystroke ) => `A tooltip for ${ label } and ${ keystroke }.`\n\t\t *\n\t\t * @observable\n\t\t * @default false\n\t\t * @member {Boolean|String|Function} #tooltip\n\t\t */\n\t\tthis.set( 'tooltip' );\n\n\t\t/**\n\t\t * (Optional) The position of the tooltip. See {@link module:ui/tooltip/tooltipview~TooltipView#position}\n\t\t * to learn more about the available position values.\n\t\t *\n\t\t * **Note:** It makes sense only when the {@link #tooltip `tooltip` attribute} is defined.\n\t\t *\n\t\t * @observable\n\t\t * @default 's'\n\t\t * @member {'s'|'n'} #position\n\t\t */\n\t\tthis.set( 'tooltipPosition', 's' );\n\n\t\t/**\n\t\t * The HTML type of the button. Default `button`.\n\t\t *\n\t\t * @observable\n\t\t * @member {'button'|'submit'|'reset'|'menu'} #type\n\t\t */\n\t\tthis.set( 'type', 'button' );\n\n\t\t/**\n\t\t * Controls whether the button view is \"on\". It makes sense when a feature it represents\n\t\t * is currently active, e.g. a bold button is \"on\" when the selection is in the bold text.\n\t\t *\n\t\t * To disable the button, use {@link #isEnabled} instead.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isOn\n\t\t */\n\t\tthis.set( 'isOn', false );\n\n\t\t/**\n\t\t * Controls whether the button view is enabled, i.e. it can be clicked and execute an action.\n\t\t *\n\t\t * To change the \"on\" state of the button, use {@link #isOn} instead.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', true );\n\n\t\t/**\n\t\t * Controls whether the button view is visible. Visible by default, buttons are hidden\n\t\t * using a CSS class.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isVisible\n\t\t */\n\t\tthis.set( 'isVisible', true );\n\n\t\t/**\n\t\t * (Optional) Controls whether the label of the button is hidden (e.g. an icononly button).\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #withText\n\t\t */\n\t\tthis.set( 'withText', false );\n\n\t\t/**\n\t\t * (Optional) An XML {@link module:ui/icon/iconview~IconView#content content} of the icon.\n\t\t * When defined, an {@link #iconView} will be added to the button.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #icon\n\t\t */\n\t\tthis.set( 'icon' );\n\n\t\t/**\n\t\t * (Optional) Controls the `tabindex` HTML attribute of the button. By default, the button is focusable\n\t\t * but does not included in the <kbd>Tab</kbd> order.\n\t\t *\n\t\t * @observable\n\t\t * @default -1\n\t\t * @member {String} #tabindex\n\t\t */\n\t\tthis.set( 'tabindex', -1 );\n\n\t\t/**\n\t\t * Collection of the child views inside of the button {@link #element}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\t/**\n\t\t * Tooltip of the button view. It is configurable using the {@link #tooltip tooltip attribute}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/tooltip/tooltipview~TooltipView} #tooltipView\n\t\t */\n\t\tthis.tooltipView = this._createTooltipView();\n\n\t\t/**\n\t\t * Label of the button view. It is configurable using the {@link #label label attribute}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/view~View} #labelView\n\t\t */\n\t\tthis.labelView = this._createLabelView();\n\n\t\t/**\n\t\t * Tooltip of the button bound to the template.\n\t\t *\n\t\t * @see #tooltip\n\t\t * @see #_getTooltipString\n\t\t * @private\n\t\t * @observable\n\t\t * @member {Boolean} #_tooltipString\n\t\t */\n\t\tthis.bind( '_tooltipString' ).to(\n\t\t\tthis, 'tooltip',\n\t\t\tthis, 'label',\n\t\t\tthis, 'keystroke',\n\t\t\tthis._getTooltipString.bind( this )\n\t\t);\n\n\t\t/**\n\t\t * (Optional) The icon view of the button. Only present when the {@link #icon icon attribute} is defined.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/icon/iconview~IconView} #iconView\n\t\t */\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'button',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-button',\n\t\t\t\t\tbind.to( 'isEnabled', value => value ? 'ck-enabled' : 'ck-disabled' ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value ),\n\t\t\t\t\tbind.to( 'isOn', value => value ? 'ck-on' : 'ck-off' ),\n\t\t\t\t\tbind.if( 'withText', 'ck-button_with-text' )\n\t\t\t\t],\n\t\t\t\ttype: bind.to( 'type', value => value ? value : 'button' ),\n\t\t\t\ttabindex: bind.to( 'tabindex' )\n\t\t\t},\n\n\t\t\tchildren: this.children,\n\n\t\t\ton: {\n\t\t\t\tmousedown: bind.to( evt => {\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t} ),\n\n\t\t\t\tclick: bind.to( evt => {\n\t\t\t\t\t// We can't make the button disabled using the disabled attribute, because it won't be focusable.\n\t\t\t\t\t// Though, shouldn't this condition be moved to the button controller?\n\t\t\t\t\tif ( this.isEnabled ) {\n\t\t\t\t\t\tthis.fire( 'execute' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Prevent the default when button is disabled, to block e.g.\n\t\t\t\t\t\t// automatic form submitting. See ckeditor/ckeditor5-link#74.\n\t\t\t\t\t\tevt.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Fired when the button view is clicked. It won't be fired when the button {@link #isEnabled}\n\t\t * is `false`.\n\t\t *\n\t\t * @event execute\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tif ( this.icon ) {\n\t\t\tconst iconView = this.iconView = new IconView();\n\n\t\t\ticonView.bind( 'content' ).to( this, 'icon' );\n\n\t\t\tthis.children.add( iconView );\n\t\t}\n\n\t\tthis.children.add( this.tooltipView );\n\t\tthis.children.add( this.labelView );\n\t}\n\n\t/**\n\t * Focuses the {@link #element} of the button.\n\t */\n\tfocus() {\n\t\tthis.element.focus();\n\t}\n\n\t/**\n\t * Creates a {@link module:ui/tooltip/tooltipview~TooltipView} instance and binds it with button\n\t * attributes.\n\t *\n\t * @private\n\t * @returns {module:ui/tooltip/tooltipview~TooltipView}\n\t */\n\t_createTooltipView() {\n\t\tconst tooltipView = new TooltipView();\n\n\t\ttooltipView.bind( 'text' ).to( this, '_tooltipString' );\n\t\ttooltipView.bind( 'position' ).to( this, 'tooltipPosition' );\n\n\t\treturn tooltipView;\n\t}\n\n\t/**\n\t * Creates a label view instance and binds it with button attributes.\n\t *\n\t * @private\n\t * @returns {module:ui/view~View}\n\t */\n\t_createLabelView() {\n\t\tconst labelView = new View();\n\n\t\tlabelView.setTemplate( {\n\t\t\ttag: 'span',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck-button__label' ]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: this.bindTemplate.to( 'label' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\treturn labelView;\n\t}\n\n\t/**\n\t * Gets the text for the {@link #tooltipView} from the combination of\n\t * {@link #tooltip}, {@link #label} and {@link #keystroke} attributes.\n\t *\n\t * @private\n\t * @see #tooltip\n\t * @see #_tooltipString\n\t * @param {Boolean|String|Function} tooltip Button tooltip.\n\t * @param {String} label Button label.\n\t * @param {String} keystroke Button keystroke.\n\t * @returns {String}\n\t */\n\t_getTooltipString( tooltip, label, keystroke ) {\n\t\tif ( tooltip ) {\n\t\t\tif ( typeof tooltip == 'string' ) {\n\t\t\t\treturn tooltip;\n\t\t\t} else {\n\t\t\t\tif ( keystroke ) {\n\t\t\t\t\tkeystroke = getEnvKeystrokeText( keystroke );\n\t\t\t\t}\n\n\t\t\t\tif ( tooltip instanceof Function ) {\n\t\t\t\t\treturn tooltip( label, keystroke );\n\t\t\t\t} else {\n\t\t\t\t\treturn `${ label }${ keystroke ? ` (${ keystroke })` : '' }`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn '';\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/button/buttonview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module undo/undo\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport UndoEngine from './undoengine';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport undoIcon from '../theme/icons/undo.svg';\nimport redoIcon from '../theme/icons/redo.svg';\n/**\n * The undo feature. It introduces the Undo and Redo buttons to the editor.\n *\n * Below is the explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:\n *\n * Whenever a {@link module:engine/model/delta/delta~Delta delta} is applied to the\n * {@link module:engine/model/document~Document document}, it is saved to `History` as is.\n * The {@link module:engine/model/batch~Batch batch} that owns that delta is also saved, in\n * {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the\n * delta was applied. A batch is saved instead of the delta because changes are undone batch-by-batch, not delta-by-delta\n * and a batch is seen as one undo step.\n *\n * After some changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:\n *\n *\t\t History Undo stack\n *\t\t=========== ==================================\n *\t\t[delta A1] [batch A]\n *\t\t[delta B1] [batch B]\n *\t\t[delta B2] [batch C]\n *\t\t[delta C1]\n *\t\t[delta C2]\n *\t\t[delta B3]\n *\t\t[delta C3]\n *\n * Where deltas starting with the same letter are from same batch.\n *\n * Undoing a batch means that a set of deltas which will reverse the effects of that batch needs to be generated. For example, if a batch\n * added several letters, undoing the batch should remove them. It is important to apply undoing deltas in the reversed order,\n * so if a batch has delta `X`, `Y`, `Z`, reversed deltas `Zr`, `Yr` and `Xr` need to be applied. Otherwise reversed delta\n * `Xr` would operate on a wrong document state, because delta `X` does not know that deltas `Y` and `Z` happened.\n *\n * After deltas from an undone batch got {@link module:engine/model/delta/delta~Delta#getReversed reversed},\n * one needs to make sure if they are ready to be applied. In the scenario above, delta `C3` is the last delta and `C3r`\n * bases on up-to-date document state, so it can be applied to the document.\n *\n *\t\t History Undo stack\n *\t\t============= ==================================\n *\t\t[ delta A1 ] [ batch A ]\n *\t\t[ delta B1 ] [ batch B ]\n *\t\t[ delta B2 ] [ processing undoing batch C ]\n *\t\t[ delta C1 ]\n *\t\t[ delta C2 ]\n *\t\t[ delta B3 ]\n *\t\t[ delta C3 ]\n *\t\t[ delta C3r ]\n *\n * Next is delta `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be\n * transformed by deltas from history that happened after it, so it \"knows\" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,\n * where `*` means \"transformed by\". Rest of deltas from that batch are processed in the same fashion.\n *\n *\t\t History Undo stack Redo stack\n *\t\t============= ================================== ==================================\n *\t\t[ delta A1 ] [ batch A ] [ batch Cr ]\n *\t\t[ delta B1 ] [ batch B ]\n *\t\t[ delta B2 ]\n *\t\t[ delta C1 ]\n *\t\t[ delta C2 ]\n *\t\t[ delta B3 ]\n *\t\t[ delta C3 ]\n *\t\t[ delta C3r ]\n *\t\t[ delta C2' ]\n *\t\t[ delta C1' ]\n *\n * Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.\n * The same algorithm applies: deltas from a batch (i.e. `A1`) are reversed and then transformed by deltas stored in history.\n *\n * Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Deltas from\n * batch that is re-done are reversed-back, transformed in proper order and applied to the document.\n *\n *\t\t History Undo stack Redo stack\n *\t\t============= ================================== ==================================\n *\t\t[ delta A1 ] [ batch A ]\n *\t\t[ delta B1 ] [ batch B ]\n *\t\t[ delta B2 ] [ batch Crr ]\n *\t\t[ delta C1 ]\n *\t\t[ delta C2 ]\n *\t\t[ delta B3 ]\n *\t\t[ delta C3 ]\n *\t\t[ delta C3r ]\n *\t\t[ delta C2' ]\n *\t\t[ delta C1' ]\n *\t\t[ delta C1'r]\n *\t\t[ delta C2'r]\n *\t\t[ delta C3rr]\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Undo extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [UndoEngine];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'Undo';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n this._addButton('undo', t('Undo'), 'CTRL+Z', undoIcon);\n this._addButton('redo', t('Redo'), 'CTRL+Y', redoIcon);\n editor.keystrokes.set('CTRL+Z', 'undo');\n editor.keystrokes.set('CTRL+Y', 'redo');\n editor.keystrokes.set('CTRL+SHIFT+Z', 'redo');\n }\n /**\n\t * Creates a button for the specified command.\n\t *\n\t * @private\n\t * @param {String} name Command name.\n\t * @param {String} label Button label.\n\t * @param {String} keystroke Command keystroke.\n\t * @param {String} Icon Source of the icon.\n\t */\n _addButton(name, label, keystroke, Icon) {\n const editor = this.editor;\n const command = editor.commands.get(name);\n editor.ui.componentFactory.add(name, locale => {\n const view = new ButtonView(locale);\n view.set({\n label,\n icon: Icon,\n keystroke,\n tooltip: true\n });\n view.bind('isEnabled').to(command, 'isEnabled');\n this.listenTo(view, 'execute', () => editor.execute(name));\n return view;\n });\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-undo/src/undo.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module essentials/essentials\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';\nimport Enter from '@ckeditor/ckeditor5-enter/src/enter';\nimport Typing from '@ckeditor/ckeditor5-typing/src/typing';\nimport Undo from '@ckeditor/ckeditor5-undo/src/undo';\n\n/**\n * A plugin including all essential editing features. It represents a set of features that enables similar functionalities\n * to a `<textarea>` element.\n *\n * It includes:\n *\n * * {@link module:clipboard/clipboard~Clipboard},\n * * {@link module:enter/enter~Enter},\n * * {@link module:typing/typing~Typing},\n * * {@link module:undo/undo~Undo}.\n *\n * This plugin set does not define any block-level containers (such as {@link module:paragraph/paragraph~Paragraph}).\n * If your editor is supposed to handle block content, make sure to include it.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Essentials extends Plugin {\n\tstatic get requires() {\n\t\treturn [ Clipboard, Enter, Typing, Undo ];\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-essentials/src/essentials.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module upload/filereader\n */\n\n/* globals window */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * FileReader class - wrapper over native FileReader.\n */\nexport default class FileReader {\n\tconstructor() {\n\t\tconst reader = new window.FileReader();\n\n\t\t/**\n\t\t * Instance of native FileReader.\n\t\t *\n\t\t * @private\n\t\t * @member {FileReader} #_reader\n\t\t */\n\t\tthis._reader = reader;\n\n\t\t/**\n\t\t * Number of bytes loaded.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #loaded\n\t\t */\n\t\tthis.set( 'loaded', 0 );\n\n\t\treader.onprogress = evt => {\n\t\t\tthis.loaded = evt.loaded;\n\t\t};\n\t}\n\n\t/**\n\t * Returns error that occurred during file reading.\n\t *\n\t * @returns {Error}\n\t */\n\tget error() {\n\t\treturn this._reader.error;\n\t}\n\n\t/**\n\t * Reads provided file.\n\t *\n\t * @param {File} file Native File object.\n\t * @returns {Promise} Returns a promise that will resolve with file's contents. Promise can be rejected in case of\n\t * error or when reading process is aborted.\n\t */\n\tread( file ) {\n\t\tconst reader = this._reader;\n\t\tthis.total = file.size;\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\treader.onload = () => {\n\t\t\t\tresolve( reader.result );\n\t\t\t};\n\n\t\t\treader.onerror = () => {\n\t\t\t\treject( 'error' );\n\t\t\t};\n\n\t\t\treader.onabort = () => {\n\t\t\t\treject( 'aborted' );\n\t\t\t};\n\n\t\t\tthis._reader.readAsDataURL( file );\n\t\t} );\n\t}\n\n\t/**\n\t * Aborts file reader.\n\t */\n\tabort() {\n\t\tthis._reader.abort();\n\t}\n}\n\nmix( FileReader, ObservableMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/filereader.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module upload/filerepository\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\nimport FileReader from './filereader.js';\n\nimport uid from '@ckeditor/ckeditor5-utils/src/uid.js';\n\n/**\n * File repository plugin. A central point for managing file upload.\n *\n * To use it, first you need an upload adapter. Upload adapter's job is to handle communication with the server\n * (sending the file and handling server's response). You can use one of the existing plugins introducing upload adapters\n * (e.g. {@link module:easy-image/cloudservicesuploadadapter~CloudServicesUploadAdapter} or\n * {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter}) or write your own one\n * (which boils down to setting the {@link ~FileRepository#createAdapter} factory function see\n * {@link module:upload/filerepository~Adapter `Adapter` interface} documentation).\n *\n * Then, you can use {@link module:upload/filerepository~FileRepository#createLoader `createLoader()`} and the returned\n * {@link module:upload/filerepository~FileLoader} instance to load and upload files.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class FileRepository extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'FileRepository';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\t/**\n\t\t * Collection of loaders associated with this repository.\n\t\t *\n\t\t * @member {module:utils/collection~Collection} #loaders\n\t\t */\n\t\tthis.loaders = new Collection();\n\n\t\t/**\n\t\t * A factory function which should be defined before using `FileRepository`.\n\t\t *\n\t\t * It should return a new instance of {@link module:upload/filerepository~Adapter} that will be used to upload files.\n\t\t * {@link module:upload/filerepository~FileLoader} instance associated with the adapter\n\t\t * will be passed to that function.\n\t\t *\n\t\t * For more information and example see {@link module:upload/filerepository~Adapter}.\n\t\t *\n\t\t * @member {Function} #createAdapter\n\t\t */\n\n\t\t/**\n\t\t * Number of bytes uploaded.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #uploaded\n\t\t */\n\t\tthis.set( 'uploaded', 0 );\n\n\t\t/**\n\t\t * Number of total bytes to upload.\n\t\t *\n\t\t * It might be different than the file size because of headers and additional data.\n\t\t * It contains `null` if value is not available yet, so it's better to use {@link #uploadedPercent} to monitor\n\t\t * the progress.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number|null} #uploadTotal\n\t\t */\n\t\tthis.set( 'uploadTotal', null );\n\n\t\t/**\n\t\t * Upload progress in percents.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #uploadedPercent\n\t\t */\n\t\tthis.bind( 'uploadedPercent' ).to( this, 'uploaded', this, 'uploadTotal', ( uploaded, total ) => {\n\t\t\treturn total ? ( uploaded / total * 100 ) : 0;\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the loader associated with specified file.\n\t *\n\t * To get loader by id use `fileRepository.loaders.get( id )`.\n\t *\n\t * @param {File} file Native file handle.\n\t * @returns {module:upload/filerepository~FileLoader|null}\n\t */\n\tgetLoader( file ) {\n\t\tfor ( const loader of this.loaders ) {\n\t\t\tif ( loader.file == file ) {\n\t\t\t\treturn loader;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Creates a loader instance for the given file.\n\t *\n\t * Requires {@link #createAdapter} factory to be defined.\n\t *\n\t * @param {File} file Native File object.\n\t * @returns {module:upload/filerepository~FileLoader|null}\n\t */\n\tcreateLoader( file ) {\n\t\tif ( !this.createAdapter ) {\n\t\t\t/**\n\t\t\t * You need to enable an upload adapter in order to be able to upload files.\n\t\t\t *\n\t\t\t * This warning shows up when {@link module:upload/filerepository~FileRepository} is being used\n\t\t\t * without {@link #createAdapter definining an upload adapter}.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the {@glink builds/index CKEditor 5 Builds}**\n\t\t\t * it means that you did not configure any of the upload adapters available by default in those builds.\n\t\t\t * See:\n\t\t\t *\n\t\t\t * * {@link module:core/editor/editorconfig~EditorConfig#cloudServices `config.cloudServices`} for\n\t\t\t * Easy Image with Cloud Services integration,\n\t\t\t * * {@link module:core/editor/editorconfig~EditorConfig#ckfinder `config.ckfinder`} for CKFinder\n\t\t\t * file upload integration.\n\t\t\t *\n\t\t\t * **If you see this warning when using a custom build** there is a chance that you enabled\n\t\t\t * a feature like {@link module:upload/imageupload~ImageUpload},\n\t\t\t * or {@link module:upload/imageuploadbutton~ImageUploadButton} but you did not enable any upload adapter.\n\t\t\t * You can choose one of the existing upload adapters:\n\t\t\t *\n\t\t\t * * {@link module:easy-image/cloudservicesuploadadapter~CloudServicesUploadAdapter}\n\t\t\t * (remember to {@link module:core/editor/editorconfig~EditorConfig#cloudServices configure it})\n\t\t\t * * {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter}\n\t\t\t * (remember to {@link module:core/editor/editorconfig~EditorConfig#ckfinder configure it})\n\t\t\t *\n\t\t\t * You can also implement your own upload adapter (in which case, please refer\n\t\t\t * to the {@link ~Adapter `Adapter` interface} documentation).\n\t\t\t *\n\t\t\t * @error filerepository-no-adapter\n\t\t\t */\n\t\t\tlog.error( 'filerepository-no-adapter: Upload adapter is not defined.' );\n\n\t\t\treturn null;\n\t\t}\n\n\t\tconst loader = new FileLoader( file );\n\t\tloader._adapter = this.createAdapter( loader );\n\n\t\tthis.loaders.add( loader );\n\n\t\tloader.on( 'change:uploaded', () => {\n\t\t\tlet aggregatedUploaded = 0;\n\n\t\t\tfor ( const loader of this.loaders ) {\n\t\t\t\taggregatedUploaded += loader.uploaded;\n\t\t\t}\n\n\t\t\tthis.uploaded = aggregatedUploaded;\n\t\t} );\n\n\t\tloader.on( 'change:uploadTotal', () => {\n\t\t\tlet aggregatedTotal = 0;\n\n\t\t\tfor ( const loader of this.loaders ) {\n\t\t\t\tif ( loader.uploadTotal ) {\n\t\t\t\t\taggregatedTotal += loader.uploadTotal;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.uploadTotal = aggregatedTotal;\n\t\t} );\n\n\t\treturn loader;\n\t}\n\n\t/**\n\t * Destroys the given loader.\n\t *\n\t * @param {File|module:upload/filerepository~FileLoader} fileOrLoader File associated with that loader or loader\n\t * itself.\n\t */\n\tdestroyLoader( fileOrLoader ) {\n\t\tconst loader = fileOrLoader instanceof FileLoader ? fileOrLoader : this.getLoader( fileOrLoader );\n\n\t\tloader._destroy();\n\n\t\tthis.loaders.remove( loader );\n\t}\n}\n\nmix( FileRepository, ObservableMixin );\n\n/**\n * File loader class.\n * It is used to control the process of file reading and uploading using specified adapter.\n */\nclass FileLoader {\n\t/**\n\t * Creates a new instance of `FileLoader`.\n\t *\n\t * @param {File} file A native file instance.\n\t * @param {module:upload/filerepository~Adapter} adapter\n\t */\n\tconstructor( file, adapter ) {\n\t\t/**\n\t\t * Unique id of FileLoader instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.id = uid();\n\n\t\t/**\n\t\t * A `File` instance associated with this file loader.\n\t\t *\n\t\t * @readonly\n\t\t * @member {File}\n\t\t */\n\t\tthis.file = file;\n\n\t\t/**\n\t\t * Adapter instance associated with this file loader.\n\t\t *\n\t\t * @private\n\t\t * @member {module:upload/filerepository~Adapter}\n\t\t */\n\t\tthis._adapter = adapter;\n\n\t\t/**\n\t\t * FileReader used by FileLoader.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:upload/filereader~FileReader}\n\t\t */\n\t\tthis._reader = new FileReader();\n\n\t\t/**\n\t\t * Current status of FileLoader. It can be one of the following:\n\t\t *\n\t\t * * 'idle',\n\t\t * * 'reading',\n\t\t * * 'uploading',\n\t\t * * 'aborted',\n\t\t * * 'error'.\n\t\t *\n\t\t * When reading status can change in a following way:\n\t\t *\n\t\t * `idle` -> `reading` -> `idle`\n\t\t * `idle` -> `reading -> `aborted`\n\t\t * `idle` -> `reading -> `error`\n\t\t *\n\t\t * When uploading status can change in a following way:\n\t\t *\n\t\t * `idle` -> `uploading` -> `idle`\n\t\t * `idle` -> `uploading` -> `aborted`\n\t\t * `idle` -> `uploading` -> `error`\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {String} #status\n\t\t */\n\t\tthis.set( 'status', 'idle' );\n\n\t\t/**\n\t\t * Number of bytes uploaded.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #uploaded\n\t\t */\n\t\tthis.set( 'uploaded', 0 );\n\n\t\t/**\n\t\t * Number of total bytes to upload.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number|null} #uploadTotal\n\t\t */\n\t\tthis.set( 'uploadTotal', null );\n\n\t\t/**\n\t\t * Upload progress in percents.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #uploadedPercent\n\t\t */\n\t\tthis.bind( 'uploadedPercent' ).to( this, 'uploaded', this, 'uploadTotal', ( uploaded, total ) => {\n\t\t\treturn total ? ( uploaded / total * 100 ) : 0;\n\t\t} );\n\n\t\t/**\n\t\t * Response of the upload.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Object|null} #uploadResponse\n\t\t */\n\t\tthis.set( 'uploadResponse', null );\n\t}\n\n\t/**\n\t * Reads file using {@link module:upload/filereader~FileReader}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-read-wrong-status` when status\n\t * is different than `idle`.\n\t *\n\t * Example usage:\n\t *\n\t *\tfileLoader.read()\n\t *\t\t.then( data => { ... } )\n\t *\t\t.catch( err => {\n\t *\t\t\tif ( err === 'aborted' ) {\n\t *\t\t\t\tconsole.log( 'Reading aborted.' );\n\t *\t\t\t} else {\n\t *\t\t\t\tconsole.log( 'Reading error.', err );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * @returns {Promise} Returns promise that will be resolved with read data. Promise will be rejected if error\n\t * occurs or if read process is aborted.\n\t */\n\tread() {\n\t\tif ( this.status != 'idle' ) {\n\t\t\tthrow new CKEditorError( 'filerepository-read-wrong-status: You cannot call read if the status is different than idle.' );\n\t\t}\n\n\t\tthis.status = 'reading';\n\n\t\treturn this._reader.read( this.file )\n\t\t\t.then( data => {\n\t\t\t\tthis.status = 'idle';\n\n\t\t\t\treturn data;\n\t\t\t} )\n\t\t\t.catch( err => {\n\t\t\t\tif ( err === 'aborted' ) {\n\t\t\t\t\tthis.status = 'aborted';\n\t\t\t\t\tthrow 'aborted';\n\t\t\t\t}\n\n\t\t\t\tthis.status = 'error';\n\t\t\t\tthrow this._reader.error;\n\t\t\t} );\n\t}\n\n\t/**\n\t * Reads file using the provided {@link module:upload/filerepository~Adapter}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-upload-wrong-status` when status\n\t * is different than `idle`.\n\t * Example usage:\n\t *\n\t *\tfileLoader.upload()\n\t *\t\t.then( data => { ... } )\n\t *\t\t.catch( e => {\n\t *\t\t\tif ( e === 'aborted' ) {\n\t *\t\t\t\tconsole.log( 'Uploading aborted.' );\n\t *\t\t\t} else {\n\t *\t\t\t\tconsole.log( 'Uploading error.', e );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * @returns {Promise} Returns promise that will be resolved with response data. Promise will be rejected if error\n\t * occurs or if read process is aborted.\n\t */\n\tupload() {\n\t\tif ( this.status != 'idle' ) {\n\t\t\tthrow new CKEditorError( 'filerepository-upload-wrong-status: You cannot call upload if the status is different than idle.' );\n\t\t}\n\n\t\tthis.status = 'uploading';\n\n\t\treturn this._adapter.upload()\n\t\t\t.then( data => {\n\t\t\t\tthis.uploadResponse = data;\n\t\t\t\tthis.status = 'idle';\n\n\t\t\t\treturn data;\n\t\t\t} )\n\t\t\t.catch( err => {\n\t\t\t\tif ( this.status === 'aborted' ) {\n\t\t\t\t\tthrow 'aborted';\n\t\t\t\t}\n\n\t\t\t\tthis.status = 'error';\n\t\t\t\tthrow err;\n\t\t\t} );\n\t}\n\n\t/**\n\t * Aborts loading process.\n\t */\n\tabort() {\n\t\tconst status = this.status;\n\t\tthis.status = 'aborted';\n\n\t\tif ( status == 'reading' ) {\n\t\t\tthis._reader.abort();\n\t\t}\n\n\t\tif ( status == 'uploading' && this._adapter.abort ) {\n\t\t\tthis._adapter.abort();\n\t\t}\n\n\t\tthis._destroy();\n\t}\n\n\t/**\n\t * Performs cleanup.\n\t *\n\t * @private\n\t */\n\t_destroy() {\n\t\tthis._reader = undefined;\n\t\tthis._adapter = undefined;\n\t\tthis.data = undefined;\n\t\tthis.uploadResponse = undefined;\n\t\tthis.file = undefined;\n\t}\n}\n\nmix( FileLoader, ObservableMixin );\n\n/**\n * Adapter interface used by FileRepository to handle file upload. Adapter is a bridge between the editor and server that\n * handles file uploads. It should contain logic necessary to initiate upload process and monitor its progress.\n *\n * It should implement two methods:\n *\n * * {@link module:upload/filerepository~Adapter#upload `upload()`},\n * * {@link module:upload/filerepository~Adapter#abort `abort()`}.\n *\n * Example adapter implementation:\n *\n *\t\tclass Adapter {\n *\t\t\tconstructor( loader ) {\n *\t\t\t\t// Save Loader instance to update upload progress.\n *\t\t\t\tthis.loader = loader;\n *\t\t\t}\n *\n *\t\t\tupload() {\n *\t\t\t\t// Update loader's progress.\n *\t\t\t\tserver.onUploadProgress( data => {\n *\t\t\t\t\tloader.uploadTotal = data.total;\n *\t\t\t\t\tloader.uploaded = data.uploaded;\n *\t\t\t\t} ):\n *\n *\t\t\t\t// Return promise that will be resolved when file is uploaded.\n *\t\t\t\treturn server.upload( loader.file );\n *\t\t\t}\n *\n *\t\t\tabort() {\n *\t\t\t\t// Reject promise returned from upload() method.\n *\t\t\t\tserver.abortUpload();\n *\t\t\t}\n *\t\t}\n *\n * Then adapter can be set to be used by {@link module:upload/filerepository~FileRepository FileRepository}:\n *\n *\t\teditor.plugins.get( 'FileRepository' ).createAdapter = function( loader ) {\n *\t\t\treturn new Adapter( loader );\n *\t\t};\n *\n * @interface Adapter\n */\n\n/**\n * Executes the upload process.\n * This method should return a promise that will resolve when data will be uploaded to server. Promise should be\n * resolved with an object containing information about uploaded file:\n *\n *\t\t{\n *\t\t\tdefault: 'http://server/default-size.image.png'\n *\t\t}\n *\n * Additionally, other image sizes can be provided:\n *\n *\t\t{\n *\t\t\tdefault: 'http://server/default-size.image.png',\n *\t\t\t'160': 'http://server/size-160.image.png',\n *\t\t\t'500': 'http://server/size-500.image.png',\n *\t\t\t'1000': 'http://server/size-1000.image.png',\n *\t\t\t'1052': 'http://server/default-size.image.png'\n *\t\t}\n *\n * NOTE: When returning multiple images, the widest returned one should equal the default one. It is essential to\n * correctly set `width` attribute of the image. See this discussion:\n * https://github.com/ckeditor/ckeditor5-easy-image/issues/4 for more information.\n *\n * Take a look at {@link module:upload/filerepository~Adapter example Adapter implementation} and\n * {@link module:upload/filerepository~FileRepository#createAdapter createAdapter method}.\n *\n * @method module:upload/filerepository~Adapter#upload\n * @returns {Promise} Promise that should be resolved when data is uploaded.\n */\n\n/**\n * Aborts the upload process.\n * After aborting it should reject promise returned from {@link #upload upload()}.\n *\n * Take a look at {@link module:upload/filerepository~Adapter example Adapter implementation} and\n * {@link module:upload/filerepository~FileRepository#createAdapter createAdapter method}.\n *\n * @method module:upload/filerepository~Adapter#abort\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/filerepository.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module autoformat/blockautoformatengine\n */\n\nimport Range from '@ckeditor/ckeditor5-engine/src/model/range';\nimport TextProxy from '@ckeditor/ckeditor5-engine/src/model/textproxy';\n\n/**\n * The block autoformatting engine. It allows to format various block patterns. For example,\n * it can be configured to turn a paragraph starting with `*` and followed by a space into a list item.\n *\n * The autoformatting operation is integrated with the undo manager,\n * so the autoformatting step can be undone if the user's intention was not to format the text.\n *\n * See the constructors documentation to learn how to create custom inline autoformatters. You can also use\n * the {@link module:autoformat/autoformat~Autoformat} feature which enables a set of default autoformatters\n * (lists, headings, bold and italic).\n */\nexport default class BlockAutoformatEngine {\n\t/**\n\t * Creates a listener triggered on `change` event in the document.\n\t * Calls the callback when inserted text matches the regular expression or the command name\n\t * if provided instead of the callback.\n\t *\n\t * Examples of usage:\n\t *\n\t * To convert a paragraph to heading 1 when `- ` is typed, using just the commmand name:\n\t *\n\t *\t\tnew BlockAutoformatEngine( editor, /^\\- $/, 'heading1' );\n\t *\n\t * To convert a paragraph to heading 1 when `- ` is typed, using just the callback:\n\t *\n\t *\t\tnew BlockAutoformatEngine( editor, /^\\- $/, ( context ) => {\n\t *\t\t\tconst { batch, match } = context;\n\t *\t\t\tconst headingLevel = match[ 1 ].length;\n\t *\n\t *\t\t\teditor.execute( 'heading', {\n\t *\t\t\t\tbatch,\n\t *\t\t\t\tformatId: `heading${ headingLevel }`\n\t *\t\t\t} );\n\t * \t\t} );\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {RegExp} pattern The regular expression to execute on just inserted text.\n\t * @param {Function|String} callbackOrCommand The callback to execute or the command to run when the text is matched.\n\t * In case of providing the callback, it receives the following parameters:\n\t * * {module:engine/model/batch~Batch} batch Newly created batch for autoformat changes.\n\t * * {Object} match RegExp.exec() result of matching the pattern to inserted text.\n\t */\n\tconstructor( editor, pattern, callbackOrCommand ) {\n\t\tlet callback;\n\n\t\tif ( typeof callbackOrCommand == 'function' ) {\n\t\t\tcallback = callbackOrCommand;\n\t\t} else {\n\t\t\t// We assume that the actual command name was provided.\n\t\t\tconst command = callbackOrCommand;\n\n\t\t\tcallback = context => {\n\t\t\t\tconst { batch } = context;\n\n\t\t\t\t// Create new batch for removal and command execution.\n\t\t\t\teditor.execute( command, { batch } );\n\t\t\t};\n\t\t}\n\n\t\teditor.document.on( 'change', ( event, type, changes, batch ) => {\n\t\t\tif ( batch.type == 'transparent' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( type != 'insert' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Take the first element. Typing shouldn't add more than one element at once.\n\t\t\t// And if it is not typing (e.g. paste), Autoformat should not be fired.\n\t\t\tconst value = changes.range.getItems().next().value;\n\n\t\t\tif ( !( value instanceof TextProxy ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst textNode = value.textNode;\n\t\t\tconst text = textNode.data;\n\n\t\t\t// Run matching only on non-empty paragraphs.\n\t\t\tif ( textNode.parent.name !== 'paragraph' || !text ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst match = pattern.exec( text );\n\n\t\t\tif ( !match ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.document.enqueueChanges( () => {\n\t\t\t\t// Create new batch to separate typing batch from the Autoformat changes.\n\t\t\t\tconst fixBatch = editor.document.batch();\n\n\t\t\t\t// Matched range.\n\t\t\t\tconst range = Range.createFromParentsAndOffsets( textNode.parent, 0, textNode.parent, match[ 0 ].length );\n\n\t\t\t\t// Remove matched text.\n\t\t\t\tfixBatch.remove( range );\n\n\t\t\t\tcallback( { fixBatch, match } );\n\t\t\t} );\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-autoformat/src/blockautoformatengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/boldengine\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';\nimport buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';\nimport AttributeCommand from './attributecommand';\n\nconst BOLD = 'bold';\n\n/**\n * The bold engine feature.\n *\n * It registers the `bold` command and introduces the `bold` attribute in the model which renders to the view\n * as a `<strong>` element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BoldEngine extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\t// Allow bold attribute on all inline nodes.\n\t\teditor.document.schema.allow( { name: '$inline', attributes: BOLD, inside: '$block' } );\n\t\t// Temporary workaround. See https://github.com/ckeditor/ckeditor5/issues/477.\n\t\teditor.document.schema.allow( { name: '$inline', attributes: BOLD, inside: '$clipboardHolder' } );\n\n\t\t// Build converter from model to view for data and editing pipelines.\n\t\tbuildModelConverter().for( data.modelToView, editing.modelToView )\n\t\t\t.fromAttribute( BOLD )\n\t\t\t.toElement( 'strong' );\n\n\t\t// Build converter from view to model for data pipeline.\n\t\tbuildViewConverter().for( data.viewToModel )\n\t\t\t.fromElement( 'strong' )\n\t\t\t.fromElement( 'b' )\n\t\t\t.fromAttribute( 'style', { 'font-weight': 'bold' } )\n\t\t\t.toAttribute( BOLD, true );\n\n\t\t// Create bold command.\n\t\teditor.commands.add( BOLD, new AttributeCommand( editor, BOLD ) );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-basic-styles/src/boldengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module basic-styles/bold\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport BoldEngine from './boldengine';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport boldIcon from '../theme/icons/bold.svg';\n/**\n * The bold feature. It introduces the Bold button and the <kbd>Ctrl+B</kbd> keystroke.\n *\n * It uses the {@link module:basic-styles/boldengine~BoldEngine bold engine feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Bold extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [BoldEngine];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'Bold';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n const command = editor.commands.get('bold');\n const keystroke = 'CTRL+B';\n // Add bold button to feature components.\n editor.ui.componentFactory.add('bold', locale => {\n const view = new ButtonView(locale);\n view.set({\n label: t('Bold'),\n icon: boldIcon,\n keystroke,\n tooltip: true\n });\n view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(view, 'execute', () => editor.execute('bold'));\n return view;\n });\n // Set the Ctrl+B keystroke.\n editor.keystrokes.set(keystroke, 'bold');\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-basic-styles/src/bold.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/italicengine\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';\nimport buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';\nimport AttributeCommand from './attributecommand';\n\nconst ITALIC = 'italic';\n\n/**\n * The italic engine feature.\n *\n * It registers the `italic` command and introduces the `italic` attribute in the model which renders to the view\n * as an `<em>` element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ItalicEngine extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\t// Allow italic attribute on all inline nodes.\n\t\teditor.document.schema.allow( { name: '$inline', attributes: ITALIC, inside: '$block' } );\n\t\t// Temporary workaround. See https://github.com/ckeditor/ckeditor5/issues/477.\n\t\teditor.document.schema.allow( { name: '$inline', attributes: ITALIC, inside: '$clipboardHolder' } );\n\n\t\t// Build converter from model to view for data and editing pipelines.\n\t\tbuildModelConverter().for( data.modelToView, editing.modelToView )\n\t\t\t.fromAttribute( ITALIC )\n\t\t\t.toElement( 'i' );\n\n\t\t// Build converter from view to model for data pipeline.\n\t\tbuildViewConverter().for( data.viewToModel )\n\t\t\t.fromElement( 'em' )\n\t\t\t.fromElement( 'i' )\n\t\t\t.fromAttribute( 'style', { 'font-style': 'italic' } )\n\t\t\t.toAttribute( ITALIC, true );\n\n\t\t// Create italic command.\n\t\teditor.commands.add( ITALIC, new AttributeCommand( editor, ITALIC ) );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-basic-styles/src/italicengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module basic-styles/italic\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ItalicEngine from './italicengine';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport italicIcon from '../theme/icons/italic.svg';\n/**\n * The italic feature. It introduces the Italic button and the <kbd>Ctrl+I</kbd> keystroke.\n *\n * It uses the {@link module:basic-styles/italicengine~ItalicEngine italic engine feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Italic extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [ItalicEngine];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'Italic';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n const command = editor.commands.get('italic');\n const keystroke = 'CTRL+I';\n // Add bold button to feature components.\n editor.ui.componentFactory.add('italic', locale => {\n const view = new ButtonView(locale);\n view.set({\n label: t('Italic'),\n icon: italicIcon,\n keystroke,\n tooltip: true\n });\n view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(view, 'execute', () => editor.execute('italic'));\n return view;\n });\n // Set the Ctrl+I keystroke.\n editor.keystrokes.set(keystroke, 'italic');\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-basic-styles/src/italic.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module block-quote/blockquote\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport BlockQuoteEngine from './blockquoteengine';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport quoteIcon from '@ckeditor/ckeditor5-core/theme/icons/quote.svg';\nimport '../theme/theme.scss';\n/**\n * The block quote plugin.\n *\n * It introduces the `'blockQuote'` button and requires the {@link module:block-quote/blockquoteengine~BlockQuoteEngine}\n * plugin. It also changes <kbd>Enter</kbd> key behavior so it escapes block quotes when pressed in an\n * empty quoted block.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuote extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [BlockQuoteEngine];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'BlockQuote';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n const command = editor.commands.get('blockQuote');\n editor.ui.componentFactory.add('blockQuote', locale => {\n const buttonView = new ButtonView(locale);\n buttonView.set({\n label: t('Block quote'),\n icon: quoteIcon,\n tooltip: true\n });\n // Bind button model to command.\n buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(buttonView, 'execute', () => editor.execute('blockQuote'));\n return buttonView;\n });\n }\n /**\n\t * @inheritDoc\n\t */\n afterInit() {\n const editor = this.editor;\n const command = editor.commands.get('blockQuote');\n // Overwrite default Enter key behavior.\n // If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote.\n // This listener is added in afterInit in order to register it after list's feature listener.\n // We can't use a priority for this, because 'low' is already used by the enter feature, unless\n // we'd use numeric priority in this case.\n this.listenTo(this.editor.editing.view, 'enter', (evt, data) => {\n const doc = this.editor.document;\n const positionParent = doc.selection.getLastPosition().parent;\n if (doc.selection.isCollapsed && positionParent.isEmpty && command.value) {\n this.editor.execute('blockQuote');\n this.editor.editing.view.scrollToTheSelection();\n data.preventDefault();\n evt.stop();\n }\n });\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-block-quote/src/blockquote.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* eslint-env browser */\n\n'use strict';\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\n\nconst DEFAULT_OPTIONS = { refreshInterval: 3600000, autoRefresh: true };\n\n/**\n * Class representing the token used for communication with CKEditor Cloud Services.\n * Value of the token is retrieving from the specified URL and is refreshed every 1 hour by default.\n *\n * @mixes ObservableMixin\n */\nclass Token {\n\t/**\n\t * Creates `Token` instance.\n\t * Method `init` should be called after using the constructor or use `create` method instead.\n\t *\n\t * @param {String} tokenUrl Endpoint address to download the token.\n\t * @param {Object} options\n\t * @param {String} [options.initValue] Initial value of the token.\n\t * @param {Number} [options.refreshInterval=3600000] Delay between refreshes. Default 1 hour.\n\t * @param {Boolean} [options.autoRefresh=true] Specifies whether to start the refresh automatically.\n\t */\n\tconstructor( tokenUrl, options = DEFAULT_OPTIONS ) {\n\t\tif ( !tokenUrl ) {\n\t\t\tthrow new Error( '`tokenUrl` must be provided' );\n\t\t}\n\n\t\t/**\n\t\t * Value of the token.\n\t\t * The value of the token is null if `initValue` is not provided or `init` method was not called.\n\t\t * `create` method creates token with initialized value from url.\n\t\t *\n\t\t * @name value\n\t\t * @type {String}\n\t\t * @observable\n\t\t * @readonly\n\t\t * @memberOf Token#\n\t\t */\n\t\tthis.set( 'value', options.initValue );\n\n\t\t/**\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._tokenUrl = tokenUrl;\n\n\t\t/**\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._options = Object.assign( {}, DEFAULT_OPTIONS, options );\n\t}\n\n\t/**\n\t * Initializes the token.\n\t *\n\t * @returns {Promise.<Token>}\n\t */\n\tinit() {\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tif ( this._options.autoRefresh ) {\n\t\t\t\tthis._startRefreshing();\n\t\t\t}\n\n\t\t\tif ( !this.value ) {\n\t\t\t\tthis._refreshToken()\n\t\t\t\t\t.then( resolve )\n\t\t\t\t\t.catch( reject );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tresolve( this );\n\t\t} );\n\t}\n\n\t/**\n\t * Gets the new token.\n\t *\n\t * @protected\n\t * @returns {Promise.<Token>}\n\t */\n\t_refreshToken() {\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tconst xhr = new XMLHttpRequest();\n\n\t\t\txhr.open( 'GET', this._tokenUrl );\n\n\t\t\txhr.addEventListener( 'load', () => {\n\t\t\t\tconst statusCode = xhr.status;\n\t\t\t\tconst xhrResponse = xhr.response;\n\n\t\t\t\tif ( statusCode < 200 || statusCode > 299 ) {\n\t\t\t\t\treturn reject( 'Cannot download new token!' );\n\t\t\t\t}\n\n\t\t\t\tthis.set( 'value', xhrResponse );\n\n\t\t\t\treturn resolve( this );\n\t\t\t} );\n\n\t\t\txhr.addEventListener( 'error', () => reject( 'Network Error' ) );\n\t\t\txhr.addEventListener( 'abort', () => reject( 'Abort' ) );\n\n\t\t\txhr.send();\n\t\t} );\n\t}\n\n\t/**\n\t * Starts value refreshing every `refreshInterval` time.\n\t *\n\t * @protected\n\t */\n\t_startRefreshing() {\n\t\tthis._refreshInterval = setInterval( this._refreshToken.bind( this ), this._options.refreshInterval );\n\t}\n\n\t/**\n\t * Stops value refreshing.\n\t *\n\t * @protected\n\t */\n\t_stopRefreshing() {\n\t\tclearInterval( this._refreshInterval );\n\t}\n\n\t/**\n\t * Creates a initialized {@link Token} instance.\n\t *\n\t * @param {String} tokenUrl Endpoint address to download the token.\n\t * @param {Object} options\n\t * @param {String} [options.initValue] Initial value of the token.\n\t * @param {Number} [options.refreshInterval=3600000] Delay between refreshes. Default 1 hour.\n\t * @param {Boolean} [options.autoRefresh=true] Specifies whether to start the refresh automatically.\n\t * @returns {Promise.<Token>}\n\t */\n\tstatic create( tokenUrl, options = DEFAULT_OPTIONS ) {\n\t\tconst token = new Token( tokenUrl, options );\n\n\t\treturn token.init();\n\t}\n}\n\nmix( Token, ObservableMixin );\n\nexport default Token;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/@ckeditor/ckeditor-cloudservices-core/src/token/token.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module cloudservices/cloudservices\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Token from '@ckeditor/ckeditor-cloudservices-core/src/token/token';\n\n/**\n * Plugin introducing CKEditor 5's Cloud Services integration.\n * It takes care of the {@link module:cloudservices/cloudservices~CloudServicesConfig `config.cloudService`}\n * configuration options and initializes the token provider.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class CloudServices extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst config = editor.config;\n\n\t\tconst options = config.get( 'cloudServices' ) || {};\n\n\t\tfor ( const optionName in options ) {\n\t\t\tthis[ optionName ] = options[ optionName ];\n\t\t}\n\n\t\t/**\n\t\t * The authentication token URL for CKEditor Cloud Services.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String|undefined} #tokenUrl\n\t\t */\n\n\t\t/**\n\t\t * The URL to which the files should be uploaded.\n\t\t *\n\t\t * @readonly\n\t\t * @default 'https://files.cke-cs.com/upload/'\n\t\t * @member {String} #uploadUrl\n\t\t */\n\n\t\tif ( !this.uploadUrl ) {\n\t\t\tthis.uploadUrl = 'https://files.cke-cs.com/upload/';\n\t\t}\n\n\t\t/**\n\t\t * Other plugins use this token for the authorization process. It handles token requesting and refreshing.\n\t\t * Its value is `null` when {@link module:cloudservices/cloudservices~CloudServicesConfig#tokenUrl} is not provided.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Object|null} #token\n\t\t */\n\n\t\tif ( !this.tokenUrl ) {\n\t\t\tthis.token = null;\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.token = new CloudServices.Token( this.tokenUrl );\n\n\t\treturn this.token.init();\n\t}\n}\n\nCloudServices.Token = Token;\n\n/**\n * The configuration of CKEditor Cloud Services. Introduced by the {@link module:cloudservices/cloudservices~CloudServices} plugin.\n *\n * Read more in {@link module:cloudservices/cloudservices~CloudServicesConfig}.\n *\n * @member {module:cloudservices/cloudservices~CloudServicesConfig} module:core/editor/editorconfig~EditorConfig#cloudServices\n */\n\n/**\n * The configuration for all plugins using CKEditor Cloud Services.\n *\n *\t\tClassicEditor\n *\t\t\t.create( document.querySelector( '#editor' ), {\n * \t\t\t\tcloudServices: ... // CloudServices config.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface CloudServicesConfig\n */\n\n/**\n * The authentication token URL for CKEditor Cloud Services. The token is used to authenticate all plugins using Cloud Services,\n * for instance Easy Image. The token URL has to point to the service where the token is generated.\n *\n *\t\tClassicEditor\n *\t\t\t.create( document.querySelector( '#editor' ), {\n *\t\t\t\tcloudServices: {\n *\t\t\t\t\ttokenUrl: TOKEN_URL\n *\t\t\t\t},\n * \t\t\t\tplugins: [ ArticlePluginSet, EasyImage ],\n *\t\t\t\ttoolbar: [ 'headings', 'undo', 'redo', 'insertImage' ],\n *\t\t\t\timage: {\n *\t\t\t\t\ttoolbar: [ 'imageStyleFull', 'imageStyleSide', '|', 'imageTextAlternative' ]\n *\t\t\t\t}\n *\t\t\t} );\n *\n * @member {String} module:cloudservices/cloudservices~CloudServicesConfig#tokenUrl\n */\n\n/**\n * The URL to which the files should be uploaded.\n *\n * @member {String} [module:cloudservices/cloudservices~CloudServicesConfig#uploadUrl='https://files.cke-cs.com/upload/']\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-cloudservices/src/cloudservices.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n* @module easy-image/cloudservicesuploadadapter\n*/\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';\nimport UploadGateway from '@ckeditor/ckeditor-cloudservices-core/src/uploadgateway/uploadgateway';\nimport CloudServices from '@ckeditor/ckeditor5-cloudservices/src/cloudservices';\n\n/**\n * A plugin which enables upload to Cloud Services.\n *\n * It is mainly used by the {@link module:easy-image/easyimage~EasyImage} feature.\n *\n * After enabling this adapter you need to configure the Cloud Services integration through\n * {@link module:cloudservices/cloudservices~CloudServicesConfig `config.cloudServices`}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class CloudServicesUploadAdapter extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ FileRepository, CloudServices ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\tconst cloudServices = editor.plugins.get( CloudServices );\n\n\t\tconst token = cloudServices.token;\n\t\tconst uploadUrl = cloudServices.uploadUrl;\n\n\t\tif ( !token ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._uploadGateway = new CloudServicesUploadAdapter._UploadGateway( token, uploadUrl );\n\n\t\teditor.plugins.get( FileRepository ).createAdapter = loader => {\n\t\t\treturn new Adapter( this._uploadGateway, loader );\n\t\t};\n\t}\n}\n\n/**\n * @private\n */\nclass Adapter {\n\tconstructor( uploadGateway, loader ) {\n\t\tthis.uploadGateway = uploadGateway;\n\n\t\tthis.loader = loader;\n\t}\n\n\tupload() {\n\t\tthis.fileUploader = this.uploadGateway.upload( this.loader.file );\n\n\t\tthis.fileUploader.on( 'progress', ( evt, data ) => {\n\t\t\tthis.loader.uploadTotal = data.total;\n\t\t\tthis.loader.uploaded = data.uploaded;\n\t\t} );\n\n\t\treturn this.fileUploader.send();\n\t}\n\n\tabort() {\n\t\tthis.fileUploader.abort();\n\t}\n}\n\n// Store the API in static property to easily overwrite it in tests.\n// Too bad dependency injection does not work in Webpack + ES 6 (const) + Babel.\nCloudServicesUploadAdapter._UploadGateway = UploadGateway;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-easy-image/src/cloudservicesuploadadapter.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagetextalternative/imagetextalternativeengine\n */\n\nimport ImageTextAlternativeCommand from './imagetextalternativecommand';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * The image text alternative engine plugin.\n * Registers the `imageTextAlternative` command.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageTextAlternativeEngine extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tthis.editor.commands.add( 'imageTextAlternative', new ImageTextAlternativeCommand( this.editor ) );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagetextalternative/imagetextalternativeengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/labeledinput/labeledinputview\n */\n\nimport View from '../view';\nimport uid from '@ckeditor/ckeditor5-utils/src/uid';\n\nimport LabelView from '../label/labelview';\n\n/**\n * The labeled input view class.\n *\n * @extends module:ui/view~View\n */\nexport default class LabeledInputView extends View {\n\t/**\n\t * Creates an instance of the labeled input view class.\n\t *\n\t * @param {module:utils/locale~Locale} locale The locale instance.\n\t * @param {Function} InputView Constructor of the input view.\n\t */\n\tconstructor( locale, InputView ) {\n\t\tsuper( locale );\n\n\t\tconst id = `ck-input-${ uid() }`;\n\n\t\t/**\n\t\t * The text of the label.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #label\n\t\t */\n\t\tthis.set( 'label' );\n\n\t\t/**\n\t\t * The value of the input.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #value\n\t\t */\n\t\tthis.set( 'value' );\n\n\t\t/**\n\t\t * Controls whether the component is in read-only mode.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * The label view.\n\t\t *\n\t\t * @member {module:ui/label/labelview~LabelView} #labelView\n\t\t */\n\t\tthis.labelView = this._createLabelView( id );\n\n\t\t/**\n\t\t * The input view.\n\t\t *\n\t\t * @member {module:ui/view~View} #inputView\n\t\t */\n\t\tthis.inputView = this._createInputView( InputView, id );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\tbind.if( 'isReadOnly', 'ck-disabled' )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis.labelView,\n\t\t\t\tthis.inputView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Creates label view class instance and bind with view.\n\t *\n\t * @private\n\t * @param {String} id Unique id to set as labelView#for attribute.\n\t * @returns {module:ui/label/labelview~LabelView}\n\t */\n\t_createLabelView( id ) {\n\t\tconst labelView = new LabelView( this.locale );\n\n\t\tlabelView.for = id;\n\t\tlabelView.bind( 'text' ).to( this, 'label' );\n\n\t\treturn labelView;\n\t}\n\n\t/**\n\t * Creates input view class instance and bind with view.\n\t *\n\t * @private\n\t * @param {Function} InputView Input view constructor.\n\t * @param {String} id Unique id to set as inputView#id attribute.\n\t * @returns {module:ui/inputtext/inputtextview~InputTextView}\n\t */\n\t_createInputView( InputView, id ) {\n\t\tconst inputView = new InputView( this.locale );\n\n\t\tinputView.id = id;\n\t\tinputView.bind( 'value' ).to( this );\n\t\tinputView.bind( 'isReadOnly' ).to( this );\n\n\t\treturn inputView;\n\t}\n\n\t/**\n\t * Moves the focus to the input and selects the value.\n\t */\n\tselect() {\n\t\tthis.inputView.select();\n\t}\n\n\t/**\n\t * Focuses the input.\n\t */\n\tfocus() {\n\t\tthis.inputView.focus();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/labeledinput/labeledinputview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/inputtext/inputtextview\n */\n\nimport View from '../view';\n\n/**\n * The text input view class.\n *\n * @extends module:ui/view~View\n */\nexport default class InputTextView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The value of the input.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #value\n\t\t */\n\t\tthis.set( 'value' );\n\n\t\t/**\n\t\t * The `id` attribute of the input (i.e. to pair with a `<label>` element).\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #id\n\t\t */\n\t\tthis.set( 'id' );\n\n\t\t/**\n\t\t * The `placeholder` attribute of the input.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #placeholder\n\t\t */\n\t\tthis.set( 'placeholder' );\n\n\t\t/**\n\t\t * Controls whether the input view is in read-only mode.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'input',\n\t\t\tattributes: {\n\t\t\t\ttype: 'text',\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-input',\n\t\t\t\t\t'ck-input-text'\n\t\t\t\t],\n\t\t\t\tid: bind.to( 'id' ),\n\t\t\t\tplaceholder: bind.to( 'placeholder' ),\n\t\t\t\treadonly: bind.to( 'isReadOnly' ),\n\t\t\t\tvalue: bind.to( 'value' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Moves the focus to the input and selects the value.\n\t */\n\tselect() {\n\t\tthis.element.select();\n\t}\n\n\t/**\n\t * Focuses the input.\n\t */\n\tfocus() {\n\t\tthis.element.focus();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/inputtext/inputtextview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imagetextalternative\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport ImageTextAlternativeEngine from './imagetextalternative/imagetextalternativeengine';\nimport clickOutsideHandler from '@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler';\nimport TextAlternativeFormView from './imagetextalternative/ui/textalternativeformview';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\nimport textAlternativeIcon from '@ckeditor/ckeditor5-core/theme/icons/low-vision.svg';\nimport {\n repositionContextualBalloon,\n getBalloonPositionData\n} from './image/ui/utils';\nimport { isImageWidgetSelected } from './image/utils';\nimport '../theme/imagetextalternative/theme.scss';\n/**\n * The image text alternative plugin.\n *\n * The plugin uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageTextAlternative extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [\n ImageTextAlternativeEngine,\n ContextualBalloon\n ];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'ImageTextAlternative';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n this._createButton();\n this._createForm();\n }\n /**\n\t * Creates a button showing the balloon panel for changing the image text alternative and\n\t * registers it in the editor {@link module:ui/componentfactory~ComponentFactory ComponentFactory}.\n\t *\n\t * @private\n\t */\n _createButton() {\n const editor = this.editor;\n const command = editor.commands.get('imageTextAlternative');\n const t = editor.t;\n editor.ui.componentFactory.add('imageTextAlternative', locale => {\n const view = new ButtonView(locale);\n view.set({\n label: t('Change image text alternative'),\n icon: textAlternativeIcon,\n tooltip: true\n });\n view.bind('isEnabled').to(command, 'isEnabled');\n this.listenTo(view, 'execute', () => this._showForm());\n return view;\n });\n }\n /**\n\t * Creates the {@link module:image/imagetextalternative/ui/textalternativeformview~TextAlternativeFormView}\n\t * form.\n\t *\n\t * @private\n\t */\n _createForm() {\n const editor = this.editor;\n const editingView = editor.editing.view;\n /**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n this._balloon = this.editor.plugins.get('ContextualBalloon');\n /**\n\t\t * A form containing a textarea and buttons, used to change the `alt` text value.\n\t\t *\n\t\t * @member {module:image/imagetextalternative/ui/textalternativeformview~TextAlternativeFormView} #form\n\t\t */\n this._form = new TextAlternativeFormView(editor.locale);\n // Render the form so its #element is available for clickOutsideHandler.\n this._form.render();\n this.listenTo(this._form, 'submit', () => {\n editor.execute('imageTextAlternative', { newValue: this._form.labeledInput.inputView.element.value });\n this._hideForm(true);\n });\n this.listenTo(this._form, 'cancel', () => {\n this._hideForm(true);\n });\n // Close the form on Esc key press.\n this._form.keystrokes.set('Esc', (data, cancel) => {\n this._hideForm(true);\n cancel();\n });\n // Reposition the balloon or hide the form if an image widget is no longer selected.\n this.listenTo(editingView, 'render', () => {\n if (!isImageWidgetSelected(editingView.selection)) {\n this._hideForm(true);\n } else if (this._isVisible) {\n repositionContextualBalloon(editor);\n }\n }, { priority: 'low' });\n // Close on click outside of balloon panel element.\n clickOutsideHandler({\n emitter: this._form,\n activator: () => this._isVisible,\n contextElements: [this._form.element],\n callback: () => this._hideForm()\n });\n }\n /**\n\t * Shows the {@link #_form} in the {@link #_balloon}.\n\t *\n\t * @private\n\t */\n _showForm() {\n if (this._isVisible) {\n return;\n }\n const editor = this.editor;\n const command = editor.commands.get('imageTextAlternative');\n const labeledInput = this._form.labeledInput;\n if (!this._balloon.hasView(this._form)) {\n this._balloon.add({\n view: this._form,\n position: getBalloonPositionData(editor)\n });\n }\n // Make sure that each time the panel shows up, the field remains in sync with the value of\n // the command. If the user typed in the input, then canceled the balloon (`labeledInput#value`\n // stays unaltered) and re-opened it without changing the value of the command, they would see the\n // old value instead of the actual value of the command.\n // https://github.com/ckeditor/ckeditor5-image/issues/114\n labeledInput.value = labeledInput.inputView.element.value = command.value || '';\n this._form.labeledInput.select();\n }\n /**\n\t * Removes the {@link #_form} from the {@link #_balloon}.\n\t *\n\t * @param {Boolean} [focusEditable=false] Controls whether the editing view is focused afterwards.\n\t * @private\n\t */\n _hideForm(focusEditable) {\n if (!this._isVisible) {\n return;\n }\n this._balloon.remove(this._form);\n if (focusEditable) {\n this.editor.editing.view.focus();\n }\n }\n /**\n\t * Returns `true` when the {@link #_form} is the visible view\n\t * in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n get _isVisible() {\n return this._balloon.visibleView == this._form;\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagetextalternative.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageEngine from './image/imageengine';\nimport Widget from '@ckeditor/ckeditor5-widget/src/widget';\nimport ImageTextAlternative from './imagetextalternative';\nimport { isImageWidgetSelected } from './image/utils';\n\nimport '../theme/theme.scss';\n\n/**\n * The image plugin.\n *\n * Uses the {@link module:image/image/imageengine~ImageEngine}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Image extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageEngine, Widget, ImageTextAlternative ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Image';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst contextualToolbar = editor.plugins.get( 'ContextualToolbar' );\n\n\t\t// If `ContextualToolbar` plugin is loaded, it should be disabled for images\n\t\t// which have their own toolbar to avoid duplication.\n\t\t// https://github.com/ckeditor/ckeditor5-image/issues/110\n\t\tif ( contextualToolbar ) {\n\t\t\tthis.listenTo( contextualToolbar, 'show', evt => {\n\t\t\t\tif ( isImageWidgetSelected( editor.editing.view.selection ) ) {\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}, { priority: 'high' } );\n\t\t}\n\t}\n}\n\n/**\n * The configuration of the image features. Used by the image features in `@ckeditor/ckeditor5-image` package.\n *\n * Read more in {@link module:image/image~ImageConfig}.\n *\n * @member {module:image/image~ImageConfig} module:core/editor/editorconfig~EditorConfig#image\n */\n\n/**\n * The configuration of the image features. Used by the image features in `@ckeditor/ckeditor5-image` package.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\timage: ... // Image feature options.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface ImageConfig\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/image.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';\nimport ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';\nimport ModelSelection from '@ckeditor/ckeditor5-engine/src/model/selection';\nimport FileRepository from './filerepository';\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\n/**\n * @module upload/imageuploadcommand\n */\n\n/**\n * Image upload command.\n *\n * @extends module:core/command~Command\n */\nexport default class ImageUploadCommand extends Command {\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options Options for executed command.\n\t * @param {File} options.file Image file to upload.\n\t * @param {module:engine/model/position~Position} [options.insertAt] Position at which the image should be inserted.\n\t * If the position is not specified the image will be inserted into the current selection.\n\t * Note: You can use the {@link module:upload/utils~findOptimalInsertionPosition} function to calculate\n\t * (e.g. based on the current selection) a position which is more optimal from UX perspective.\n\t * @param {module:engine/model/batch~Batch} [options.batch] Batch to collect all the change steps.\n\t * New batch will be created if this option is not set.\n\t */\n\texecute( options ) {\n\t\tconst editor = this.editor;\n\t\tconst doc = editor.document;\n\t\tconst batch = options.batch || doc.batch();\n\t\tconst file = options.file;\n\t\tconst selection = doc.selection;\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tconst loader = fileRepository.createLoader( file );\n\n\t\t\t// Do not throw when upload adapter is not set. FileRepository will log an error anyway.\n\t\t\tif ( !loader ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst imageElement = new ModelElement( 'image', {\n\t\t\t\tuploadId: loader.id\n\t\t\t} );\n\n\t\t\tlet insertAtSelection;\n\n\t\t\tif ( options.insertAt ) {\n\t\t\t\tinsertAtSelection = new ModelSelection( [ new ModelRange( options.insertAt ) ] );\n\t\t\t} else {\n\t\t\t\tinsertAtSelection = doc.selection;\n\t\t\t}\n\n\t\t\teditor.data.insertContent( imageElement, insertAtSelection, batch );\n\n\t\t\t// Inserting an image might've failed due to schema regulations.\n\t\t\tif ( imageElement.parent ) {\n\t\t\t\tselection.setRanges( [ ModelRange.createOn( imageElement ) ] );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n// Returns correct image insertion position.\n//\n// @param {module:engine/model/document~Document} doc\n// @returns {module:engine/model/position~Position|undefined}\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/imageuploadcommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/notification/notification\n */\n\n/* globals window */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * The Notification plugin.\n *\n * This plugin sends few base types of notifications: `success`, `info` and `warning`. This notifications need to be\n * handled and displayed by plugin responsible for showing UI of the notifications. Using this plugin for dispatching\n * notifications makes possible to switch the notifications UI.\n *\n * Note that every unhandled and not stopped `warning` notification will be displayed as system alert.\n * See {@link module:ui/notification/notification~Notification#showWarning}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Notification extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Notification';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\t// Each unhandled and not stopped `show:warning` event is displayed as system alert.\n\t\tthis.on( 'show:warning', ( evt, data ) => {\n\t\t\twindow.alert( data.message ); // eslint-disable-line no-alert\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Shows success notification.\n\t *\n\t * At default it fires `show:success` event with given data but event namespace can be extended\n\t * by `data.namespace` option e.g.\n\t *\n\t * \t\tshowSuccess( 'Image is uploaded.', {\n\t * \t\t\tnamespace: 'upload:image'\n\t * \t\t} );\n\t *\n\t * will fire `show:success:upload:image` event.\n\t * Title of the notification can be provided:\n\t *\n\t *\t\tshowSuccess( 'Image is uploaded.', {\n\t *\t\t\ttitle: 'Image upload success'\n\t *\t\t});\n\t *\n\t * @param {String} message Content of the notification.\n\t * @param {Object} [data={}] Additional data.\n\t * @param {String} [data.namespace] Additional event namespace.\n\t * @param {String} [data.title] Title of the notification.\n\t */\n\tshowSuccess( message, data = {} ) {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'success',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Shows info notification.\n\t *\n\t * At default it fires `show:info` event with given data but event namespace can be extended\n\t * by `data.namespace` option e.g.\n\t *\n\t * \t\tshowInfo( 'Editor is offline.', {\n\t * \t\t\tnamespace: 'editor:status'\n\t * \t\t} );\n\t *\n\t * will fire `show:info:editor:status` event.\n\t * Title of the notification can be provided:\n\t *\n\t *\t\tshowInfo( 'Editor is offline.', {\n\t *\t\t\ttitle: 'Network information'\n\t *\t\t});\n\t *\n\t * @param {String} message Content of the notification.\n\t * @param {Object} [data={}] Additional data.\n\t * @param {String} [data.namespace] Additional event namespace.\n\t * @param {String} [data.title] Title of the notification.\n\t */\n\tshowInfo( message, data = {} ) {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'info',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Shows warning notification.\n\t *\n\t * At default it fires `show:warning` event with given data but event namespace can be extended\n\t * by `data.namespace` option e.g.\n\t *\n\t * \t\tshowWarning( 'Image upload error.', {\n\t * \t\t\tnamespace: 'upload:image'\n\t * \t\t} );\n\t *\n\t * will fire `show:warning:upload:image` event.\n\t * Title of the notification can be provided:\n\t *\n\t *\t\tshowWarning( 'Image upload error.', {\n\t *\t\t\ttitle: 'Upload failed'\n\t *\t\t});\n\t *\n\t * Note that each unhandled and not stopped `warning` notification will be displayed as system alert.\n\t * Plugin responsible for displaying warnings should `stop()` the event to prevent of displaying it as alert:\n\t *\n\t * \t\tnotifications.on( 'show:warning', ( evt, data ) => {\n\t * \t\t\t// Do something with data.\n\t *\n\t * \t\t\t// Stop this event to prevent of displaying as alert.\n\t * \t\t\tevt.stop();\n\t * \t\t} );\n\t *\n\t * You can attach many listeners to the same event and `stop()` this event in the listener with the low priority:\n\t *\n\t * \t\tnotifications.on( 'show:warning', ( evt, data ) => {\n\t * \t\t\t// Show warning in the UI, but not stop it.\n\t * \t\t} );\n\t *\n\t * \t\tnotifications.on( 'show:warning', ( evt, data ) => {\n\t * \t\t\t// Log warning to some error tracker.\n\t *\n\t * \t\t\t// Stop this event to prevent of displaying as alert.\n\t * \t\t\tevt.stop();\n\t * \t\t}, { priority: 'low' } );\n\t *\n\t * @param {String} message Content of the notification.\n\t * @param {Object} [data={}] Additional data.\n\t * @param {String} [data.namespace] Additional event namespace.\n\t * @param {String} [data.title] Title of the notification.\n\t */\n\tshowWarning( message, data = {} ) {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'warning',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Fires `show` event with specified type, namespace and message.\n\t *\n\t * @private\n\t * @param {Object} data Message data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {'success'|'info'|'warning'} data.type Type of message.\n\t * @param {String} [data.namespace] Additional event namespace.\n\t * @param {String} [data.title=''] Title of the notification.\n\t */\n\t_showNotification( data ) {\n\t\tconst event = `show:${ data.type }` + ( data.namespace ? `:${ data.namespace }` : '' );\n\n\t\tthis.fire( event, {\n\t\t\tmessage: data.message,\n\t\t\ttype: data.type,\n\t\t\ttitle: data.title || ''\n\t\t} );\n\t}\n\n\t/**\n\t * Fired when one of `showSuccess`, `showInfo`, `showWarning` methods is called.\n\t *\n\t * @event show\n\t * @param {Object} data Notification data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {String} data.title Title of the notification.\n\t * @param {'success'|'info'|'warning'} data.type Type of notification.\n\t */\n\n\t/**\n\t * Fired when `showSuccess` method is called.\n\t *\n\t * @event show:success\n\t * @param {Object} data Notification data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {String} data.title Title of the notification.\n\t * @param {'success'} data.type Type of notification.\n\t */\n\n\t/**\n\t * Fired when `showInfo` method is called.\n\t *\n\t * @event show:info\n\t * @param {Object} data Notification data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {String} data.title Title of the notification.\n\t * @param {'info'} data.type Type of notification.\n\t */\n\n\t/**\n\t * Fired when `showWarning` method is called.\n\t *\n\t * When this event won't be handled and stopped by `event.stop()` then data.message of this event will\n\t * be automatically displayed as system alert.\n\t *\n\t * @event show:warning\n\t * @param {Object} data Notification data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {String} data.title Title of the notification.\n\t * @param {'warning'} data.type Type of notification.\n\t */\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/notification/notification.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module upload/imageuploadbutton\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageUploadEngine from './imageuploadengine';\nimport FileDialogButtonView from './ui/filedialogbuttonview';\nimport imageIcon from '@ckeditor/ckeditor5-core/theme/icons/image.svg';\nimport {\n isImageType,\n findOptimalInsertionPosition\n} from './utils';\n/**\n * Image upload button plugin.\n * Adds `insertImage` button to UI component factory.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadButton extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [ImageUploadEngine];\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n // Setup `insertImage` button.\n editor.ui.componentFactory.add('insertImage', locale => {\n const view = new FileDialogButtonView(locale);\n const command = editor.commands.get('imageUpload');\n view.set({\n acceptedType: 'image/*',\n allowMultipleFiles: true\n });\n view.buttonView.set({\n label: t('Insert image'),\n icon: imageIcon,\n tooltip: true\n });\n view.bind('isEnabled').to(command);\n view.on('done', (evt, files) => {\n for (const file of Array.from(files)) {\n const insertAt = findOptimalInsertionPosition(editor.document.selection);\n if (isImageType(file)) {\n editor.execute('imageUpload', {\n file,\n insertAt\n });\n }\n }\n });\n return view;\n });\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/src/imageuploadbutton.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module easy-image/easyimage\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport CloudServicesUploadAdapter from './cloudservicesuploadadapter';\nimport Image from '@ckeditor/ckeditor5-image/src/image';\nimport ImageUpload from '@ckeditor/ckeditor5-upload/src/imageupload';\n\n/**\n * The Easy Image feature.\n *\n * This plugin enables:\n *\n * * {@link module:image/image~Image},\n * * {@link module:upload/imageupload~ImageUpload},\n * * {@link module:easy-image/cloudservicesuploadadapter~CloudServicesUploadAdapter}.\n *\n * After enabling the Easy Image plugin you need to configure the Cloud Services integration through\n * {@link module:cloudservices/cloudservices~CloudServicesConfig `config.cloudServices`}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class EasyImage extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [\n\t\t\tCloudServicesUploadAdapter,\n\t\t\tImage,\n\t\t\tImageUpload\n\t\t];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'EasyImage';\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-easy-image/src/easyimage.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/model\n */\n\nimport extend from '@ckeditor/ckeditor5-utils/src/lib/lodash/extend';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\n\n/**\n * The base MVC model class.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Model {\n\t/**\n\t * Creates a new Model instance.\n\t *\n\t * @param {Object} [attributes] The model state attributes to be defined during the instance creation.\n\t * @param {Object} [properties] The (out of state) properties to be appended to the instance during creation.\n\t */\n\tconstructor( attributes, properties ) {\n\t\t// Extend this instance with the additional (out of state) properties.\n\t\tif ( properties ) {\n\t\t\textend( this, properties );\n\t\t}\n\n\t\t// Initialize the attributes.\n\t\tif ( attributes ) {\n\t\t\tthis.set( attributes );\n\t\t}\n\t}\n}\n\nmix( Model, ObservableMixin );\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/model.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/list/listview\n */\n\nimport View from '../view';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '../focuscycler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n\n/**\n * The list view class.\n *\n * @extends module:ui/view~View\n */\nexport default class ListView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Collection of the child list views.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.items = this.createCollection();\n\n\t\t/**\n\t\t * Tracks information about DOM focus in the list.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\t/**\n\t\t * Helps cycling over focusable {@link #items} in the list.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.items,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate list items backwards using the arrowup key.\n\t\t\t\tfocusPrevious: 'arrowup',\n\n\t\t\t\t// Navigate toolbar items forwards using the arrowdown key.\n\t\t\t\tfocusNext: 'arrowdown',\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'ul',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-list'\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.items\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Items added before rendering should be known to the #focusTracker.\n\t\tfor ( const item of this.items ) {\n\t\t\tthis.focusTracker.add( item.element );\n\t\t}\n\n\t\tthis.items.on( 'add', ( evt, item ) => {\n\t\t\tthis.focusTracker.add( item.element );\n\t\t} );\n\n\t\tthis.items.on( 'remove', ( evt, item ) => {\n\t\t\tthis.focusTracker.remove( item.element );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\t}\n\n\t/**\n\t * Focuses the first focusable in {@link #items}.\n\t */\n\tfocus() {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the last focusable in {@link #items}.\n\t */\n\tfocusLast() {\n\t\tthis._focusCycler.focusLast();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/list/listview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/list/listitemview\n */\n\nimport View from '../view';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n\n/**\n * The list item view class.\n *\n * @extends module:ui/view~View\n */\nexport default class ListItemView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Controls the `tabindex` attribute of the item.\n\t\t *\n\t\t * @observable\n\t\t * @default -1\n\t\t * @member {String} #tabindex\n\t\t */\n\t\tthis.set( 'tabindex', -1 );\n\n\t\t/**\n\t\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'li',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-list__item',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isActive', 'ck-list__item_active' )\n\t\t\t\t],\n\t\t\t\tstyle: bind.to( 'style' ),\n\t\t\t\ttabindex: bind.to( 'tabindex' )\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: bind.to( 'label' )\n\t\t\t\t}\n\t\t\t],\n\n\t\t\ton: {\n\t\t\t\tclick: bind.to( 'execute' )\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * The label of the list item.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #label\n\t\t */\n\n\t\t/**\n\t\t * (Optional) The DOM style attribute of the list item.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #style\n\t\t */\n\n\t\t/**\n\t\t * (Optional) The additional class set on the {@link #element}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #class\n\t\t */\n\n\t\t/**\n\t\t * (Optional) When set, it marks the item as active among the others.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isActive\n\t\t */\n\n\t\t/**\n\t\t * Fired when the list item has been clicked.\n\t\t *\n\t\t * @event execute\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tconst onKeystrokePress = ( data, cancel ) => {\n\t\t\tthis.fire( 'execute' );\n\t\t\tcancel();\n\t\t};\n\n\t\tthis.keystrokes.listenTo( this.element );\n\n\t\t// Execute on Enter and Space key press.\n\t\tthis.keystrokes.set( 'Enter', onKeystrokePress );\n\t\tthis.keystrokes.set( 'Space', onKeystrokePress );\n\t}\n\n\t/**\n\t * Focuses the list item.\n\t */\n\tfocus() {\n\t\tthis.element.focus();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/list/listitemview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/dropdown/dropdownview\n */\n\nimport View from '../view';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n\n/**\n * The dropdown view class.\n *\n *\t\tconst button = new ButtonView( locale );\n *\t\tconst panel = new DropdownPanelView( locale );\n *\t\tconst dropdown = new DropdownView( locale, button, panel );\n *\n *\t\tpanel.element.textContent = 'Content of the panel';\n *\t\tbutton.set( {\n *\t\t\tlabel: 'A dropdown',\n *\t\t\twithText: true\n *\t\t} );\n *\n *\t\tdropdown.render();\n *\n *\t\t// Will render a dropdown with a panel containing a \"Content of the panel\" text.\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * Also see {@link module:ui/dropdown/createdropdown~createDropdown} and\n * {@link module:ui/dropdown/list/createlistdropdown~createListDropdown} to learn about different\n * dropdown creation helpers.\n *\n * @extends module:ui/view~View\n */\nexport default class DropdownView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale, buttonView, panelView ) {\n\t\tsuper( locale );\n\n\t\t// Extend button's template before it's registered as a child of the dropdown because\n\t\t// by doing so, its #element is rendered and any postrender template extension will\n\t\t// not be reflected in DOM.\n\t\tbuttonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-dropdown__button'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Button of the dropdown view. Clicking the button opens the {@link #panelView}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/button/buttonview~ButtonView} #buttonView\n\t\t */\n\t\tthis.buttonView = buttonView;\n\n\t\t/**\n\t\t * Panel of the dropdown. It opens when the {@link #buttonView} is\n\t\t * {@link module:ui/button/buttonview~ButtonView#event:execute executed} (i.e. clicked).\n\t\t *\n\t\t * Child views can be added to the panel's `children` collection:\n\t\t *\n\t\t *\t\tdropdown.panelView.children.add( childView );\n\t\t *\n\t\t * See {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#children} and\n\t\t * {@link module:ui/viewcollection~ViewCollection#add}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/dropdown/dropdownpanelview~DropdownPanelView} #panelView\n\t\t */\n\t\tthis.panelView = panelView;\n\n\t\t/**\n\t\t * Controls whether the dropdown view is open, i.e. shows or hides the {@link #panelView panel}.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isOpen\n\t\t */\n\t\tthis.set( 'isOpen', false );\n\n\t\t/**\n\t\t * Tracks information about DOM focus in the dropdown.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t\t * keystrokes of the dropdown:\n\t\t *\n\t\t * * <kbd>▼</kbd> opens the dropdown,\n\t\t * * <kbd>◀</kbd> and <kbd>Esc</kbd> closes the dropdown.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-dropdown'\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tbuttonView,\n\t\t\t\tpanelView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Toggle the the dropdown when it's button has been clicked.\n\t\tthis.listenTo( this.buttonView, 'execute', () => {\n\t\t\tthis.isOpen = !this.isOpen;\n\t\t} );\n\n\t\t// Toggle the visibility of the panel when the dropdown becomes open.\n\t\tthis.panelView.bind( 'isVisible' ).to( this, 'isOpen' );\n\n\t\t// Listen for keystrokes coming from within #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\n\t\t// Register #element in the focus tracker.\n\t\tthis.focusTracker.add( this.element );\n\n\t\tconst closeDropdown = ( data, cancel ) => {\n\t\t\tif ( this.isOpen ) {\n\t\t\t\tthis.buttonView.focus();\n\t\t\t\tthis.isOpen = false;\n\t\t\t\tcancel();\n\t\t\t}\n\t\t};\n\n\t\t// Open the dropdown panel using the arrow down key, just like with return or space.\n\t\tthis.keystrokes.set( 'arrowdown', ( data, cancel ) => {\n\t\t\t// Don't open if the dropdown is disabled or already open.\n\t\t\tif ( this.buttonView.isEnabled && !this.isOpen ) {\n\t\t\t\tthis.isOpen = true;\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\n\t\t// Block the right arrow key (until nested dropdowns are implemented).\n\t\tthis.keystrokes.set( 'arrowright', ( data, cancel ) => {\n\t\t\tif ( this.isOpen ) {\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\n\t\t// Close the dropdown using the arrow left/escape key.\n\t\tthis.keystrokes.set( 'arrowleft', closeDropdown );\n\t\tthis.keystrokes.set( 'esc', closeDropdown );\n\t}\n\n\t/**\n\t * Focuses the {@link #buttonView}.\n\t */\n\tfocus() {\n\t\tthis.buttonView.focus();\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/dropdown/dropdownview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/dropdown/dropdownpanelview\n */\n\nimport View from '../view';\n\n/**\n * The dropdown panel view class.\n *\n * See {@link module:ui/dropdown/dropdownview~DropdownView} to learn about the common usage.\n *\n * @extends module:ui/view~View\n */\nexport default class DropdownPanelView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * Controls whether the panel is visible.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isVisible\n\t\t */\n\t\tthis.set( 'isVisible', false );\n\n\t\t/**\n\t\t * Collection of the child views in this panel.\n\t\t *\n\t\t * A common child type is the {@link module:list/list~List}. See\n\t\t * {@link module:ui/dropdown/list/createlistdropdown~createListDropdown} to learn more\n\t\t * about list dropdowns.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-dropdown__panel',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-dropdown__panel-visible' )\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.children,\n\n\t\t\ton: {\n\t\t\t\t// Drag and drop in the panel should not break the selection in the editor.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/228\n\t\t\t\tselectstart: bind.to( evt => evt.preventDefault() )\n\t\t\t}\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-ui/src/dropdown/dropdownpanelview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagecaption\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageCaptionEngine from './imagecaption/imagecaptionengine';\nimport '../theme/imagecaption/theme.scss';\n\n/**\n * The image caption plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageCaption extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageCaptionEngine ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageCaption';\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagecaption.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagestyle/imagestylecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { isImage } from '../image/utils';\n\n/**\n * The image style command. It is used to apply different image styles.\n *\n * @extends module:core/command~Command\n */\nexport default class ImageStyleCommand extends Command {\n\t/**\n\t * Creates an instance of the image style command. Each command instance is handling one style.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {module:image/imagestyle/imagestyleengine~ImageStyleFormat} styles A style to be applied by this command.\n\t */\n\tconstructor( editor, style ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The value of the command &mdash; `true` if a style handled by the command is applied on a currently selected image,\n\t\t * `false` otherwise.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #value\n\t\t */\n\n\t\t/**\n\t\t * A style handled by this command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:image/imagestyle/imagestyleengine~ImageStyleFormat} #style\n\t\t */\n\t\tthis.style = style;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst element = this.editor.document.selection.getSelectedElement();\n\n\t\tthis.isEnabled = isImage( element );\n\n\t\tif ( !element ) {\n\t\t\tthis.value = false;\n\t\t} else if ( this.style.isDefault ) {\n\t\t\tthis.value = !element.hasAttribute( 'imageStyle' );\n\t\t} else {\n\t\t\tthis.value = ( element.getAttribute( 'imageStyle' ) == this.style.name );\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {module:engine/model/batch~Batch} [options.batch] A batch to collect all the change steps. A new batch will be\n\t * created if this option is not set.\n\t */\n\texecute( options = {} ) {\n\t\tif ( this.value ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst doc = this.editor.document;\n\t\tconst imageElement = doc.selection.getSelectedElement();\n\n\t\tdoc.enqueueChanges( () => {\n\t\t\tconst batch = options.batch || doc.batch();\n\n\t\t\t// Default style means that there is no `imageStyle` attribute in the model.\n\t\t\t// https://github.com/ckeditor/ckeditor5-image/issues/147\n\t\t\tif ( this.style.isDefault ) {\n\t\t\t\tbatch.removeAttribute( imageElement, 'imageStyle' );\n\t\t\t} else {\n\t\t\t\tbatch.setAttribute( imageElement, 'imageStyle', this.style.name );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagestyle/imagestylecommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagetoolbar\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\nimport { isImageWidgetSelected } from './image/utils';\nimport { repositionContextualBalloon, getBalloonPositionData } from './image/ui/utils';\n\nconst balloonClassName = 'ck-toolbar-container ck-editor-toolbar-container';\n\n/**\n * The image toolbar class. Creates an image toolbar that shows up when the image widget is selected.\n *\n * Toolbar components are created using the editor {@link module:ui/componentfactory~ComponentFactory ComponentFactory}\n * based on the {@link module:core/editor/editor~Editor#config configuration} stored under `image.toolbar`.\n *\n * The toolbar uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageToolbar extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageToolbar';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst toolbarConfig = editor.config.get( 'image.toolbar' );\n\n\t\t// Don't add the toolbar if there is no configuration.\n\t\tif ( !toolbarConfig || !toolbarConfig.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n\t\tthis._balloon = this.editor.plugins.get( 'ContextualBalloon' );\n\n\t\t/**\n\t\t * A `ToolbarView` instance used to display the buttons specific for image\n\t\t * editing.\n\t\t *\n\t\t * @protected\n\t\t * @type {module:ui/toolbar/toolbarview~ToolbarView}\n\t\t */\n\t\tthis._toolbar = new ToolbarView();\n\n\t\t// Add CSS class to the toolbar.\n\t\tthis._toolbar.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-editor-toolbar'\n\t\t\t}\n\t\t} );\n\n\t\t// Add buttons to the toolbar.\n\t\tthis._toolbar.fillFromConfig( toolbarConfig, editor.ui.componentFactory );\n\n\t\t// Show balloon panel each time image widget is selected.\n\t\tthis.listenTo( editor.editing.view, 'render', () => {\n\t\t\tthis._checkIsVisible();\n\t\t}, { priority: 'low' } );\n\n\t\t// There is no render method after focus is back in editor, we need to check if balloon panel should be visible.\n\t\tthis.listenTo( editor.ui.focusTracker, 'change:isFocused', () => {\n\t\t\tthis._checkIsVisible();\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Checks whether the toolbar should show up or hide depending on the\n\t * current selection.\n\t *\n\t * @private\n\t */\n\t_checkIsVisible() {\n\t\tconst editor = this.editor;\n\n\t\tif ( !editor.ui.focusTracker.isFocused ) {\n\t\t\tthis._hideToolbar();\n\t\t} else {\n\t\t\tif ( isImageWidgetSelected( editor.editing.view.selection ) ) {\n\t\t\t\tthis._showToolbar();\n\t\t\t} else {\n\t\t\t\tthis._hideToolbar();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Shows the {@link #_toolbar} in the {@link #_balloon}.\n\t *\n\t * @private\n\t */\n\t_showToolbar() {\n\t\tconst editor = this.editor;\n\n\t\tif ( this._isVisible ) {\n\t\t\trepositionContextualBalloon( editor );\n\t\t} else {\n\t\t\tif ( !this._balloon.hasView( this._toolbar ) ) {\n\t\t\t\tthis._balloon.add( {\n\t\t\t\t\tview: this._toolbar,\n\t\t\t\t\tposition: getBalloonPositionData( editor ),\n\t\t\t\t\tballoonClassName\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes the {@link #_toolbar} from the {@link #_balloon}.\n\t *\n\t * @private\n\t */\n\t_hideToolbar() {\n\t\tif ( !this._isVisible ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._balloon.remove( this._toolbar );\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #_toolbar} is the visible view\n\t * in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _isVisible() {\n\t\treturn this._balloon.visibleView == this._toolbar;\n\t}\n}\n\n/**\n * Items to be placed in the image toolbar.\n * The option is used by the {@link module:image/imagetoolbar~ImageToolbar} feature.\n *\n * Assuming that you use the following features:\n *\n * * {@link module:image/imagestyle~ImageStyle} (with a default configuration),\n * * {@link module:image/imagetextalternative~ImageTextAlternative}.\n *\n * Three toolbar items will be available in {@link module:ui/componentfactory~ComponentFactory}:\n * `'imageStyleFull'`, `'imageStyleSide'`, and `'imageTextAlternative'` so you can configure the toolbar like this:\n *\n *\t\tconst imageConfig = {\n *\t\t\ttoolbar: [ 'imageStyleFull', 'imageStyleSide', '|', 'imageTextAlternative' ]\n *\t\t};\n *\n * Of course, the same buttons can also be used in the\n * {@link module:core/editor/editorconfig~EditorConfig#toolbar main editor toolbar}.\n *\n * Read more about configuring toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.\n *\n * @member {Array.<String>} module:image/image~ImageConfig#toolbar\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/src/imagetoolbar.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/clickobserver\n */\n\nimport DomEventObserver from './domeventobserver';\n\n/**\n * {@link module:engine/view/document~Document#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/document~Document}\n * by a {@link module:engine/view/document~Document#addObserver} method.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class ClickObserver extends DomEventObserver {\n\tconstructor( document ) {\n\t\tsuper( document );\n\n\t\tthis.domEventType = 'click';\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when one of the editables has been clicked.\n *\n * Introduced by {@link module:engine/view/observer/clickobserver~ClickObserver}.\n *\n * Note that this event is not available by default. To make it available\n * {@link module:engine/view/observer/clickobserver~ClickObserver} needs to be added\n * to {@link module:engine/view/document~Document} by a {@link module:engine/view/document~Document#addObserver} method.\n *\n * @see module:engine/view/observer/clickobserver~ClickObserver\n * @event module:engine/view/document~Document#event:click\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/src/view/observer/clickobserver.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/linkelement\n */\n\nimport AttributeElement from '@ckeditor/ckeditor5-engine/src/view/attributeelement';\n\n/**\n * This class is to mark a specific {@link module:engine/view/node~Node} as a {@link module:link/linkelement~LinkElement}.\n * For example, there could be a situation when different features will create nodes with the same names,\n * and hence they must be identified somehow.\n *\n * @extends module:engine/view/attributelement~AttributeElement\n */\nexport default class LinkElement extends AttributeElement {\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/src/linkelement.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/unlinkcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport findLinkRange from './findlinkrange';\n\n/**\n * The unlink command. It is used by the {@link module:link/link~Link link plugin}.\n *\n * @extends module:core/command~Command\n */\nexport default class UnlinkCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this.editor.document.selection.hasAttribute( 'linkHref' );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is collapsed, removes the `linkHref` attribute from each node with the same `linkHref` attribute value.\n\t * When the selection is non-collapsed, removes the `linkHref` attribute from each node in selected ranges.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst document = this.editor.document;\n\t\tconst selection = document.selection;\n\n\t\tdocument.enqueueChanges( () => {\n\t\t\t// Get ranges to unlink.\n\t\t\tconst rangesToUnlink = selection.isCollapsed ?\n\t\t\t\t[ findLinkRange( selection.getFirstPosition(), selection.getAttribute( 'linkHref' ) ) ] : selection.getRanges();\n\n\t\t\t// Keep it as one undo step.\n\t\t\tconst batch = document.batch();\n\n\t\t\t// Remove `linkHref` attribute from specified ranges.\n\t\t\tfor ( const range of rangesToUnlink ) {\n\t\t\t\tbatch.removeAttribute( range, 'linkHref' );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/src/unlinkcommand.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/linkengine\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';\nimport buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';\nimport LinkElement from './linkelement';\nimport LinkCommand from './linkcommand';\nimport UnlinkCommand from './unlinkcommand';\n\n/**\n * The link engine feature.\n *\n * It introduces the `linkHref=\"url\"` attribute in the model which renders to the view as a `<a href=\"url\">` element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class LinkEngine extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\t// Allow link attribute on all inline nodes.\n\t\teditor.document.schema.allow( { name: '$inline', attributes: 'linkHref', inside: '$block' } );\n\t\t// Temporary workaround. See https://github.com/ckeditor/ckeditor5/issues/477.\n\t\teditor.document.schema.allow( { name: '$inline', attributes: 'linkHref', inside: '$clipboardHolder' } );\n\n\t\t// Build converter from model to view for data and editing pipelines.\n\t\tbuildModelConverter().for( data.modelToView, editing.modelToView )\n\t\t\t.fromAttribute( 'linkHref' )\n\t\t\t.toElement( linkHref => {\n\t\t\t\tconst linkElement = new LinkElement( 'a', { href: linkHref } );\n\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-link/issues/121\n\t\t\t\tlinkElement.priority = 5;\n\n\t\t\t\treturn linkElement;\n\t\t\t} );\n\n\t\t// Build converter from view to model for data pipeline.\n\t\tbuildViewConverter().for( data.viewToModel )\n\t\t\t// Convert <a> with href (value doesn't matter).\n\t\t\t.from( { name: 'a', attribute: { href: /.?/ } } )\n\t\t\t.toAttribute( viewElement => ( {\n\t\t\t\tkey: 'linkHref',\n\t\t\t\tvalue: viewElement.getAttribute( 'href' )\n\t\t\t} ) );\n\n\t\t// Create linking commands.\n\t\teditor.commands.add( 'link', new LinkCommand( editor ) );\n\t\teditor.commands.add( 'unlink', new UnlinkCommand( editor ) );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/src/linkengine.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module link/ui/linkformview\n */\nimport View from '@ckeditor/ckeditor5-ui/src/view';\nimport ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport LabeledInputView from '@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview';\nimport InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview';\nimport submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n/**\n * The link form view controller class.\n *\n * See {@link module:link/ui/linkformview~LinkFormView}.\n *\n * @extends module:ui/view~View\n */\nexport default class LinkFormView extends View {\n /**\n\t * @inheritDoc\n\t */\n constructor(locale) {\n super(locale);\n const t = locale.t;\n /**\n\t\t * Tracks information about DOM focus in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n this.focusTracker = new FocusTracker();\n /**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n this.keystrokes = new KeystrokeHandler();\n /**\n\t\t * The URL input view.\n\t\t *\n\t\t * @member {module:ui/labeledinput/labeledinputview~LabeledInputView}\n\t\t */\n this.urlInputView = this._createUrlInput();\n /**\n\t\t * The Save button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n this.saveButtonView = this._createButton(t('Save'));\n this.saveButtonView.type = 'submit';\n /**\n\t\t * The Cancel button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n this.cancelButtonView = this._createButton(t('Cancel'), 'cancel');\n /**\n\t\t * The Unlink button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n this.unlinkButtonView = this._createButton(t('Unlink'), 'unlink');\n /**\n\t\t * A collection of views which can be focused in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n this._focusables = new ViewCollection();\n /**\n\t\t * Helps cycling over {@link #_focusables} in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n this._focusCycler = new FocusCycler({\n focusables: this._focusables,\n focusTracker: this.focusTracker,\n keystrokeHandler: this.keystrokes,\n actions: {\n // Navigate form fields backwards using the Shift + Tab keystroke.\n focusPrevious: 'shift + tab',\n // Navigate form fields forwards using the Tab key.\n focusNext: 'tab'\n }\n });\n this.saveButtonView.extendTemplate({ attributes: { class: ['ck-button-action'] } });\n this.setTemplate({\n tag: 'form',\n attributes: {\n class: ['ck-link-form'],\n // https://github.com/ckeditor/ckeditor5-link/issues/90\n tabindex: '-1'\n },\n children: [\n this.urlInputView,\n {\n tag: 'div',\n attributes: { class: ['ck-link-form__actions'] },\n children: [\n this.saveButtonView,\n this.cancelButtonView,\n this.unlinkButtonView\n ]\n }\n ]\n });\n }\n /**\n\t * @inheritDoc\n\t */\n render() {\n super.render();\n submitHandler({ view: this });\n const childViews = [\n this.urlInputView,\n this.saveButtonView,\n this.cancelButtonView,\n this.unlinkButtonView\n ];\n childViews.forEach(v => {\n // Register the view as focusable.\n this._focusables.add(v);\n // Register the view in the focus tracker.\n this.focusTracker.add(v.element);\n });\n // Start listening for the keystrokes coming from #element.\n this.keystrokes.listenTo(this.element);\n }\n /**\n\t * Focuses the fist {@link #_focusables} in the form.\n\t */\n focus() {\n this._focusCycler.focusFirst();\n }\n /**\n\t * Creates a labeled input view.\n\t *\n\t * @private\n\t * @returns {module:ui/labeledinput/labeledinputview~LabeledInputView} Labeled input view instance.\n\t */\n _createUrlInput() {\n const t = this.locale.t;\n const labeledInput = new LabeledInputView(this.locale, InputTextView);\n labeledInput.label = t('Link URL');\n labeledInput.inputView.placeholder = 'https://example.com';\n return labeledInput;\n }\n /**\n\t * Creates a button view.\n\t *\n\t * @private\n\t * @param {String} label The button label\n\t * @param {String} [eventName] An event name that the `ButtonView#execute` event will be delegated to.\n\t * @returns {module:ui/button/buttonview~ButtonView} The button view instance.\n\t */\n _createButton(label, eventName) {\n const button = new ButtonView(this.locale);\n button.label = label;\n button.withText = true;\n if (eventName) {\n button.delegate('execute').to(this, eventName);\n }\n return button;\n }\n} /**\n * Fired when the form view is submitted (when one of the children triggered the submit event),\n * e.g. click on {@link #saveButtonView}.\n *\n * @event submit\n */\n /**\n * Fired when the form view is canceled, e.g. click on {@link #cancelButtonView}.\n *\n * @event cancel\n */\n /**\n * Fired when the {@link #unlinkButtonView} is clicked.\n *\n * @event unlink\n */\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/src/ui/linkformview.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module list/list\n */\nimport ListEngine from './listengine';\nimport numberedListIcon from '../theme/icons/numberedlist.svg';\nimport bulletedListIcon from '../theme/icons/bulletedlist.svg';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n/**\n * The list feature. It introduces the `numberedList` and `bulletedList` buttons that\n * allow to convert paragraphs to and from list items and indent or outdent them.\n *\n * See also {@link module:list/listengine~ListEngine}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class List extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [ListEngine];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'List';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n // Create two buttons and link them with numberedList and bulletedList commands.\n const t = this.editor.t;\n this._addButton('numberedList', t('Numbered List'), numberedListIcon);\n this._addButton('bulletedList', t('Bulleted List'), bulletedListIcon);\n // Overwrite default Enter key behavior.\n // If Enter key is pressed with selection collapsed in empty list item, outdent it instead of breaking it.\n this.listenTo(this.editor.editing.view, 'enter', (evt, data) => {\n const doc = this.editor.document;\n const positionParent = doc.selection.getLastPosition().parent;\n if (doc.selection.isCollapsed && positionParent.name == 'listItem' && positionParent.isEmpty) {\n this.editor.execute('outdentList');\n data.preventDefault();\n evt.stop();\n }\n });\n // Overwrite default Backspace key behavior.\n // If Backspace key is pressed with selection collapsed on first position in first list item, outdent it. #83\n this.listenTo(this.editor.editing.view, 'delete', (evt, data) => {\n // Check conditions from those that require less computations like those immediately available.\n if (data.direction !== 'backward') {\n return;\n }\n const selection = this.editor.document.selection;\n if (!selection.isCollapsed) {\n return;\n }\n const firstPosition = selection.getFirstPosition();\n if (!firstPosition.isAtStart) {\n return;\n }\n const positionParent = firstPosition.parent;\n if (positionParent.name !== 'listItem') {\n return;\n }\n const previousIsAListItem = positionParent.previousSibling && positionParent.previousSibling.name === 'listItem';\n if (previousIsAListItem) {\n return;\n }\n this.editor.execute('outdentList');\n data.preventDefault();\n evt.stop();\n }, { priority: 'high' });\n const getCommandExecuter = commandName => {\n return (data, cancel) => {\n const command = this.editor.commands.get(commandName);\n if (command.isEnabled) {\n this.editor.execute(commandName);\n cancel();\n }\n };\n };\n this.editor.keystrokes.set('Tab', getCommandExecuter('indentList'));\n this.editor.keystrokes.set('Shift+Tab', getCommandExecuter('outdentList'));\n }\n /**\n\t * Helper method for initializing a button and linking it with an appropriate command.\n\t *\n\t * @private\n\t * @param {String} commandName The name of the command.\n\t * @param {Object} label The button label.\n\t * @param {String} icon The source of the icon.\n\t */\n _addButton(commandName, label, icon) {\n const editor = this.editor;\n const command = editor.commands.get(commandName);\n editor.ui.componentFactory.add(commandName, locale => {\n const buttonView = new ButtonView(locale);\n buttonView.set({\n label,\n icon,\n tooltip: true\n });\n // Bind button model to command.\n buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(buttonView, 'execute', () => editor.execute(commandName));\n return buttonView;\n });\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-list/src/list.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport BalloonEditorBase from '@ckeditor/ckeditor5-editor-balloon/src/ballooneditor';\nimport EssentialsPlugin from '@ckeditor/ckeditor5-essentials/src/essentials';\nimport UploadadapterPlugin from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';\nimport AutoformatPlugin from '@ckeditor/ckeditor5-autoformat/src/autoformat';\nimport BoldPlugin from '@ckeditor/ckeditor5-basic-styles/src/bold';\nimport ItalicPlugin from '@ckeditor/ckeditor5-basic-styles/src/italic';\nimport BlockquotePlugin from '@ckeditor/ckeditor5-block-quote/src/blockquote';\nimport EasyimagePlugin from '@ckeditor/ckeditor5-easy-image/src/easyimage';\nimport HeadingPlugin from '@ckeditor/ckeditor5-heading/src/heading';\nimport ImagePlugin from '@ckeditor/ckeditor5-image/src/image';\nimport ImagecaptionPlugin from '@ckeditor/ckeditor5-image/src/imagecaption';\nimport ImagestylePlugin from '@ckeditor/ckeditor5-image/src/imagestyle';\nimport ImagetoolbarPlugin from '@ckeditor/ckeditor5-image/src/imagetoolbar';\nimport LinkPlugin from '@ckeditor/ckeditor5-link/src/link';\nimport ListPlugin from '@ckeditor/ckeditor5-list/src/list';\nimport ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph';\nimport ImageuploadPlugin from '@ckeditor/ckeditor5-upload/src/imageupload';\n\nexport default class BalloonEditor extends BalloonEditorBase {}\n\nBalloonEditor.build = {\n\tplugins: [\n\t\tEssentialsPlugin,\n\t\tUploadadapterPlugin,\n\t\tAutoformatPlugin,\n\t\tBoldPlugin,\n\t\tItalicPlugin,\n\t\tBlockquotePlugin,\n\t\tEasyimagePlugin,\n\t\tHeadingPlugin,\n\t\tImagePlugin,\n\t\tImagecaptionPlugin,\n\t\tImagestylePlugin,\n\t\tImagetoolbarPlugin,\n\t\tLinkPlugin,\n\t\tListPlugin,\n\t\tParagraphPlugin,\n\t\tImageuploadPlugin\n\t],\n\tconfig: {\n\t\ttoolbar: {\n\t\t\titems: [\n\t\t\t\t'headings',\n\t\t\t\t'bold',\n\t\t\t\t'italic',\n\t\t\t\t'link',\n\t\t\t\t'bulletedList',\n\t\t\t\t'numberedList',\n\t\t\t\t'blockQuote',\n\t\t\t\t'undo',\n\t\t\t\t'redo'\n\t\t\t]\n\t\t},\n\t\timage: {\n\t\t\ttoolbar: [\n\t\t\t\t'imageStyleFull',\n\t\t\t\t'imageStyleSide',\n\t\t\t\t'|',\n\t\t\t\t'imageTextAlternative'\n\t\t\t]\n\t\t}\n\t}\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/ckeditor.js\n// module id = null\n// module chunks = ","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\n} catch(e) {\n\t// This works if the window reference is available\n\tif(typeof window === \"object\")\n\t\tg = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 5\n// module chunks = 0","/**\n * Checks if `value` is a global object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {null|Object} Returns `value` if it's a global object, else `null`.\n */\nfunction checkGlobal(value) {\n return (value && value.Object === Object) ? value : null;\n}\n\nexport default checkGlobal;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/_checkGlobal.js\n// module id = 6\n// module chunks = 0","import constant from './constant';\nimport root from './_root';\n\n/** Used to determine if values are of the language type `Object`. */\nvar objectTypes = {\n 'function': true,\n 'object': true\n};\n\n/** Detect free variable `exports`. */\nvar freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)\n ? exports\n : undefined;\n\n/** Detect free variable `module`. */\nvar freeModule = (objectTypes[typeof module] && module && !module.nodeType)\n ? module\n : undefined;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = (freeModule && freeModule.exports === freeExports)\n ? freeExports\n : undefined;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = !Buffer ? constant(false) : function(value) {\n return value instanceof Buffer;\n};\n\nexport default isBuffer;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/isBuffer.js\n// module id = 7\n// module chunks = 0","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var object = { 'user': 'fred' };\n * var getter = _.constant(object);\n *\n * getter() === object;\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-utils/src/lib/lodash/constant.js\n// module id = 8\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-editor-balloon/theme/theme.scss\n// module id = 9\n// module chunks = 0","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \".ck-hidden{display:none!important}.ck-reset,.ck-reset_all,.ck-reset_all *,.ck-reset_all a,.ck-reset_all textarea{box-sizing:border-box;width:auto;height:auto;position:static}svg.ck-icon{min-width:20px;min-height:20px;font-size:1em;vertical-align:middle}svg.ck-icon,svg.ck-icon *{color:inherit;cursor:inherit}svg.ck-icon *{fill:currentColor}.ck-tooltip,.ck-tooltip__text:after{position:absolute;pointer-events:none;-webkit-backface-visibility:hidden}.ck-tooltip{visibility:hidden;opacity:0;display:none;z-index:999}.ck-tooltip__text{display:inline-block}.ck-tooltip__text:after{content:\\\"\\\";width:0;height:0}.ck-button,a.ck-button{display:inline-block;position:relative;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.ck-button .ck-tooltip,a.ck-button .ck-tooltip{display:block}.ck-button:hover .ck-tooltip,a.ck-button:hover .ck-tooltip{visibility:visible;opacity:1}.ck-button .ck-button__label,.ck-button:focus:not(:hover) .ck-tooltip,a.ck-button .ck-button__label,a.ck-button:focus:not(:hover) .ck-tooltip{display:none}.ck-toolbar__separator{display:inline-block}.ck-toolbar__newline{display:block;clear:left}.ck-dropdown{display:inline-block;position:relative}.ck-dropdown:after{content:\\\"\\\";width:0;height:0;pointer-events:none;z-index:1;position:absolute;top:50%;transform:translateY(-50%)}.ck-dropdown__panel{-webkit-backface-visibility:hidden;display:none;z-index:999;position:absolute;left:0;transform:translateY(100%)}.ck-dropdown__panel-visible{display:inline-block}.ck-label,.ck-list__item{display:block}.cke-voice-label{display:none}.ck-balloon-panel{display:none;position:absolute;z-index:999}.ck-balloon-panel.ck-balloon-panel_with-arrow:after,.ck-balloon-panel.ck-balloon-panel_with-arrow:before{content:\\\"\\\";position:absolute}.ck-balloon-panel.ck-balloon-panel_with-arrow:before{z-index:1}.ck-balloon-panel.ck-balloon-panel_with-arrow:after{z-index:2}.ck-balloon-panel.ck-balloon-panel_arrow_n:before,.ck-balloon-panel.ck-balloon-panel_arrow_ne:before,.ck-balloon-panel.ck-balloon-panel_arrow_nw:before{z-index:1}.ck-balloon-panel.ck-balloon-panel_arrow_n:after,.ck-balloon-panel.ck-balloon-panel_arrow_ne:after,.ck-balloon-panel.ck-balloon-panel_arrow_nw:after{z-index:2}.ck-balloon-panel.ck-balloon-panel_arrow_s:before,.ck-balloon-panel.ck-balloon-panel_arrow_se:before,.ck-balloon-panel.ck-balloon-panel_arrow_sw:before{z-index:1}.ck-balloon-panel.ck-balloon-panel_arrow_s:after,.ck-balloon-panel.ck-balloon-panel_arrow_se:after,.ck-balloon-panel.ck-balloon-panel_arrow_sw:after{z-index:2}.ck-balloon-panel_visible{display:block}.ck-editor .ck-sticky-panel .ck-sticky-panel__content_sticky{z-index:999;position:fixed;top:0}.ck-editor .ck-sticky-panel .ck-sticky-panel__content_sticky_bottom-limit{top:auto;position:absolute}.ck-reset,.ck-reset_all,.ck-reset_all *,.ck-reset_all a,.ck-reset_all textarea{margin:0;padding:0;border:0;background:transparent;text-decoration:none;vertical-align:middle;transition:none;word-wrap:break-word}.ck-reset_all,.ck-reset_all *,.ck-reset_all a,.ck-reset_all textarea{border-collapse:collapse;font:normal normal normal 12px/1.67 Helvetica,Arial,Tahoma,Verdana,Sans-Serif;color:#333;text-align:left;white-space:nowrap;cursor:auto;float:none}.ck-reset_all .ck-rtl *{text-align:right}.ck-reset_all iframe{vertical-align:inherit}.ck-reset_all textarea{white-space:pre-wrap}.ck-reset_all input[type=password],.ck-reset_all input[type=text],.ck-reset_all textarea{cursor:text}.ck-reset_all input[type=password][disabled],.ck-reset_all input[type=text][disabled],.ck-reset_all textarea[disabled]{cursor:default}.ck-reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.ck-reset_all button::-moz-focus-inner{padding:0;border:0}svg.ck-icon{width:1.67em;height:1.67em}.ck-tooltip{left:50%}.ck-tooltip__text{font-size:.9em;line-height:1.5;color:#fff;padding:.4em .64em;background:#333;position:relative;left:-50%}.ck-rounded-corners .ck-tooltip__text,.ck-tooltip__text.ck-rounded-corners{border-radius:2px}.ck-tooltip__text:after{border-style:solid;left:50%}.ck-tooltip.ck-tooltip_s{bottom:-5px;transform:translateY(100%)}.ck-tooltip.ck-tooltip_s .ck-tooltip__text:after{top:-5px;transform:translateX(-50%);border-color:transparent transparent #333;border-width:0 5px 5px}.ck-tooltip.ck-tooltip_n{top:-5px;transform:translateY(-100%)}.ck-tooltip.ck-tooltip_n .ck-tooltip__text:after{bottom:-5px;transform:translateX(-50%);border-color:#333 transparent transparent;border-width:5px 5px 0}.ck-tooltip,.ck-tooltip__text:after{transition:opacity .2s ease-in-out .2s}.ck-button,a.ck-button{background:#fff;border:1px solid #bfbfbf;white-space:nowrap;cursor:default;vertical-align:middle;padding:.4em;font-size:inherit}.ck-button:not(.ck-disabled):focus,.ck-button:not(.ck-disabled):hover,a.ck-button:not(.ck-disabled):focus,a.ck-button:not(.ck-disabled):hover{background:#e6e6e6;border-color:#acacac}.ck-button:not(.ck-disabled):active,a.ck-button:not(.ck-disabled):active{background:#d9d9d9;border-color:#a3a3a3;box-shadow:inset 0 2px 2px #bfbfbf}.ck-button.ck-disabled,a.ck-button.ck-disabled{background:#fff;border-color:#c6c6c6}.ck-button.ck-rounded-corners,.ck-rounded-corners .ck-button,.ck-rounded-corners a.ck-button,a.ck-button.ck-rounded-corners{border-radius:2px}.ck-button:focus,a.ck-button:focus{outline:none;border:1px solid #48a3f5;box-shadow:0 0 3px 2px #78bbf8}.ck-button .ck-icon,a.ck-button .ck-icon{float:left}.ck-button.ck-disabled .ck-button__label,.ck-button.ck-disabled .ck-icon,a.ck-button.ck-disabled .ck-button__label,a.ck-button.ck-disabled .ck-icon{opacity:.5}.ck-button.ck-button_with-text,a.ck-button.ck-button_with-text{padding:.4em .8em}.ck-button.ck-button_with-text .ck-icon,a.ck-button.ck-button_with-text .ck-icon{margin-left:-.4em;margin-right:.4em}.ck-button.ck-button_with-text .ck-button__label,a.ck-button.ck-button_with-text .ck-button__label{display:block}.ck-button.ck-on,a.ck-button.ck-on{background:#f7f7f7;border-color:#b9b9b9}.ck-button.ck-on:not(.ck-disabled):focus,.ck-button.ck-on:not(.ck-disabled):hover,a.ck-button.ck-on:not(.ck-disabled):focus,a.ck-button.ck-on:not(.ck-disabled):hover{background:#dedede;border-color:#a7a7a7}.ck-button.ck-on:not(.ck-disabled):active,a.ck-button.ck-on:not(.ck-disabled):active{background:#d2d2d2;border-color:#9d9d9d;box-shadow:inset 0 2px 2px #b9b9b9}.ck-button.ck-on.ck-disabled,a.ck-button.ck-on.ck-disabled{background:#f8f8f8;border-color:silver}.ck-button-action,a.ck-button-action{background:#61b145;border-color:#4e8e37;text-shadow:0 -1px #4e8e37;color:#fff}.ck-button-action:not(.ck-disabled):focus,.ck-button-action:not(.ck-disabled):hover,a.ck-button-action:not(.ck-disabled):focus,a.ck-button-action:not(.ck-disabled):hover{background:#579f3e;border-color:#467f32}.ck-button-action:not(.ck-disabled):active,a.ck-button-action:not(.ck-disabled):active{background:#52963b;border-color:#42782f;box-shadow:inset 0 2px 2px #498534}.ck-button-action.ck-disabled,a.ck-button-action.ck-disabled{background:#6fbc54;border-color:#5aa440}.ck-button-action:active,.ck-button-action:focus,.ck-button-action:hover,a.ck-button-action:active,a.ck-button-action:focus,a.ck-button-action:hover{text-shadow:0 -1px #3a6a29}.ck-button-bold,a.ck-button-bold{font-weight:700}.ck-button .ck-icon use,.ck-button .ck-icon use *,a.ck-button .ck-icon use,a.ck-button .ck-icon use *{color:inherit}.ck-button .ck-button__label,a.ck-button .ck-button__label{font-size:inherit;float:left;height:1.67em;line-height:inherit;font-weight:inherit;color:inherit;cursor:inherit}.ck-toolbar{padding:.4em;border:1px solid #bfbfbf;white-space:normal;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.ck-toolbar_floating{white-space:nowrap}.ck-rounded-corners .ck-toolbar,.ck-toolbar.ck-rounded-corners{border-radius:2px}.ck-toolbar__separator{width:1px;height:2.28em;vertical-align:middle;background:#bfbfbf}.ck-toolbar__newline{height:.4em}.ck-toolbar>*{margin-right:.4em}.ck-toolbar>:last-child{margin-right:0}.ck-toolbar-container .ck-toolbar{border:0}.ck-dropdown{font-size:inherit}.ck-dropdown:after{border-style:solid;border-width:.4em .4em 0;border-color:#707070 transparent;right:.8em}.ck-dropdown .ck-button.ck-dropdown__button{padding-right:1.6em}.ck-dropdown .ck-button.ck-dropdown__button.ck-disabled .ck-button__label{opacity:.5}.ck-dropdown .ck-button.ck-dropdown__button .ck-button__label{width:7em;overflow:hidden;text-overflow:ellipsis}.ck-dropdown__panel{background:#fff;border:1px solid #bfbfbf;bottom:1px;box-shadow:0 1px 2px 0 rgba(0,0,0,.2)}.ck-dropdown__panel.ck-rounded-corners,.ck-rounded-corners .ck-dropdown__panel{border-radius:2px}.ck-list{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;overflow:hidden;list-style-type:none;background:#fff}.ck-list.ck-rounded-corners,.ck-rounded-corners .ck-list{border-radius:2px}.ck-list__item{padding:.64em;cursor:default;min-width:12em}.ck-list__item:focus,.ck-list__item:hover{background:#f7f7f7}.ck-list__item:focus{box-shadow:0 0 3px 2px #78bbf8;position:relative;z-index:1;outline:none}.ck-list__item_active{background:#1a8bf1;color:#fff}.ck-list__item_active:focus,.ck-list__item_active:hover{background:#0e7ee2}.ck-label{font-weight:700}.ck-input-text{box-shadow:inset 2px 2px 3px rgba(0,0,0,.1);background:#fff;border:1px solid #bfbfbf;padding:.4em .64em;min-width:21em}.ck-input-text.ck-rounded-corners,.ck-rounded-corners .ck-input-text{border-radius:2px}.ck-input-text:focus{outline:none;border:1px solid #48a3f5;box-shadow:0 0 3px 2px #78bbf8,inset 2px 2px 3px rgba(0,0,0,.1)}.ck-input-text[readonly]{border:1px solid #c6c6c6;background:#f2f2f2;color:#5c5c5c}.ck-editor__editable.ck-rounded-corners,.ck-rounded-corners .ck-editor__editable{border-radius:2px}.ck-editor__editable.ck-focused{outline:none;border:1px solid #48a3f5;box-shadow:inset 2px 2px 3px rgba(0,0,0,.1)}.ck-editor__editable_inline{overflow:auto;padding:0 .8em;border:1px solid transparent}.ck-editor-toolbar .ck-button{border-width:0}.ck-editor-toolbar .ck-button.ck-disabled,.ck-editor-toolbar .ck-button:not(:hover):not(:focus):not(.ck-on){background:#f7f7f7}.ck-editor-toolbar .ck-button.ck-on{background:#dedede;border-color:#acacac}.ck-editor-toolbar .ck-button.ck-on:not(.ck-disabled):focus,.ck-editor-toolbar .ck-button.ck-on:not(.ck-disabled):hover{background:#c6c6c6;border-color:#999}.ck-editor-toolbar .ck-button.ck-on:not(.ck-disabled):active{background:#b9b9b9;border-color:#8f8f8f;box-shadow:inset 0 2px 2px #a1a1a1}.ck-editor-toolbar .ck-button.ck-on.ck-disabled{background:#f7f7f7;border-color:#bfbfbf}.ck-editor-toolbar .ck-button.ck-dropdown__button{border-width:1px}.ck-editor-toolbar .ck-button.ck-dropdown__button:not(:hover):not(:focus):not(.ck-on){background:#fff}.ck-toolbar-container .ck-editor-toolbar{background:#f7f7f7}.ck-toolbar-container.ck-editor-toolbar-container.ck-balloon-panel_arrow_n:after,.ck-toolbar-container.ck-editor-toolbar-container.ck-balloon-panel_arrow_ne:after,.ck-toolbar-container.ck-editor-toolbar-container.ck-balloon-panel_arrow_nw:after{border-bottom-color:#f7f7f7}.ck-toolbar-container.ck-editor-toolbar-container.ck-balloon-panel_arrow_s:after,.ck-toolbar-container.ck-editor-toolbar-container.ck-balloon-panel_arrow_se:after,.ck-toolbar-container.ck-editor-toolbar-container.ck-balloon-panel_arrow_sw:after{border-top-color:#f7f7f7}.ck-balloon-panel{box-shadow:0 1px 2px 0 rgba(0,0,0,.2);min-height:15px;background:#fff;border:1px solid #bfbfbf}.ck-balloon-panel.ck-rounded-corners,.ck-rounded-corners .ck-balloon-panel{border-radius:2px}.ck-balloon-panel.ck-balloon-panel_with-arrow:after,.ck-balloon-panel.ck-balloon-panel_with-arrow:before{width:0;height:0;border-style:solid}.ck-balloon-panel.ck-balloon-panel_arrow_n:after,.ck-balloon-panel.ck-balloon-panel_arrow_n:before,.ck-balloon-panel.ck-balloon-panel_arrow_ne:after,.ck-balloon-panel.ck-balloon-panel_arrow_ne:before,.ck-balloon-panel.ck-balloon-panel_arrow_nw:after,.ck-balloon-panel.ck-balloon-panel_arrow_nw:before{border-width:0 10px 15px}.ck-balloon-panel.ck-balloon-panel_arrow_n:before,.ck-balloon-panel.ck-balloon-panel_arrow_ne:before,.ck-balloon-panel.ck-balloon-panel_arrow_nw:before{border-color:transparent transparent #bfbfbf}.ck-balloon-panel.ck-balloon-panel_arrow_n:after,.ck-balloon-panel.ck-balloon-panel_arrow_ne:after,.ck-balloon-panel.ck-balloon-panel_arrow_nw:after{border-color:transparent transparent #fff;margin-top:2px}.ck-balloon-panel.ck-balloon-panel_arrow_s:after,.ck-balloon-panel.ck-balloon-panel_arrow_s:before,.ck-balloon-panel.ck-balloon-panel_arrow_se:after,.ck-balloon-panel.ck-balloon-panel_arrow_se:before,.ck-balloon-panel.ck-balloon-panel_arrow_sw:after,.ck-balloon-panel.ck-balloon-panel_arrow_sw:before{border-width:15px 10px 0}.ck-balloon-panel.ck-balloon-panel_arrow_s:before,.ck-balloon-panel.ck-balloon-panel_arrow_se:before,.ck-balloon-panel.ck-balloon-panel_arrow_sw:before{border-color:#bfbfbf transparent transparent}.ck-balloon-panel.ck-balloon-panel_arrow_s:after,.ck-balloon-panel.ck-balloon-panel_arrow_se:after,.ck-balloon-panel.ck-balloon-panel_arrow_sw:after{border-color:#fff transparent transparent;margin-bottom:2px}.ck-balloon-panel.ck-balloon-panel_arrow_n:after,.ck-balloon-panel.ck-balloon-panel_arrow_n:before{left:50%;margin-left:-10px;top:-15px}.ck-balloon-panel.ck-balloon-panel_arrow_nw:after,.ck-balloon-panel.ck-balloon-panel_arrow_nw:before{left:20px;top:-15px}.ck-balloon-panel.ck-balloon-panel_arrow_ne:after,.ck-balloon-panel.ck-balloon-panel_arrow_ne:before{right:20px;top:-15px}.ck-balloon-panel.ck-balloon-panel_arrow_s:after,.ck-balloon-panel.ck-balloon-panel_arrow_s:before{left:50%;margin-left:-10px;bottom:-15px}.ck-balloon-panel.ck-balloon-panel_arrow_sw:after,.ck-balloon-panel.ck-balloon-panel_arrow_sw:before{left:20px;bottom:-15px}.ck-balloon-panel.ck-balloon-panel_arrow_se:after,.ck-balloon-panel.ck-balloon-panel_arrow_se:before{right:20px;bottom:-15px}.ck-editor .ck-sticky-panel .ck-sticky-panel__content_sticky{box-shadow:0 1px 2px 0 rgba(0,0,0,.2);border-width:0 1px 1px;border-top-left-radius:0;border-top-right-radius:0}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-editor-balloon/theme/theme.scss\n// module id = 10\n// module chunks = 0","\n/**\n * When source maps are enabled, `style-loader` uses a link element with a data-uri to\n * embed the css on the page. This breaks all relative urls because now they are relative to a\n * bundle instead of the current page.\n *\n * One solution is to only use full urls, but that may be impossible.\n *\n * Instead, this function \"fixes\" the relative urls to be absolute according to the current page location.\n *\n * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.\n *\n */\n\nmodule.exports = function (css) {\n // get current location\n var location = typeof window !== \"undefined\" && window.location;\n\n if (!location) {\n throw new Error(\"fixUrls requires window.location\");\n }\n\n\t// blank or null?\n\tif (!css || typeof css !== \"string\") {\n\t return css;\n }\n\n var baseUrl = location.protocol + \"//\" + location.host;\n var currentDir = baseUrl + location.pathname.replace(/\\/[^\\/]*$/, \"/\");\n\n\t// convert each url(...)\n\t/*\n\tThis regular expression is just a way to recursively match brackets within\n\ta string.\n\n\t /url\\s*\\( = Match on the word \"url\" with any whitespace after it and then a parens\n\t ( = Start a capturing group\n\t (?: = Start a non-capturing group\n\t [^)(] = Match anything that isn't a parentheses\n\t | = OR\n\t \\( = Match a start parentheses\n\t (?: = Start another non-capturing groups\n\t [^)(]+ = Match anything that isn't a parentheses\n\t | = OR\n\t \\( = Match a start parentheses\n\t [^)(]* = Match anything that isn't a parentheses\n\t \\) = Match a end parentheses\n\t ) = End Group\n *\\) = Match anything and then a close parens\n ) = Close non-capturing group\n * = Match anything\n ) = Close capturing group\n\t \\) = Match a close parens\n\n\t /gi = Get all matches, not the first. Be case insensitive.\n\t */\n\tvar fixedCss = css.replace(/url\\s*\\(((?:[^)(]|\\((?:[^)(]+|\\([^)(]*\\))*\\))*)\\)/gi, function(fullMatch, origUrl) {\n\t\t// strip quotes (if they exist)\n\t\tvar unquotedOrigUrl = origUrl\n\t\t\t.trim()\n\t\t\t.replace(/^\"(.*)\"$/, function(o, $1){ return $1; })\n\t\t\t.replace(/^'(.*)'$/, function(o, $1){ return $1; });\n\n\t\t// already a full url? no change\n\t\tif (/^(#|data:|http:\\/\\/|https:\\/\\/|file:\\/\\/\\/)/i.test(unquotedOrigUrl)) {\n\t\t return fullMatch;\n\t\t}\n\n\t\t// convert the url to a full url\n\t\tvar newUrl;\n\n\t\tif (unquotedOrigUrl.indexOf(\"//\") === 0) {\n\t\t \t//TODO: should we add protocol?\n\t\t\tnewUrl = unquotedOrigUrl;\n\t\t} else if (unquotedOrigUrl.indexOf(\"/\") === 0) {\n\t\t\t// path should be relative to the base url\n\t\t\tnewUrl = baseUrl + unquotedOrigUrl; // already starts with '/'\n\t\t} else {\n\t\t\t// path should be relative to current directory\n\t\t\tnewUrl = currentDir + unquotedOrigUrl.replace(/^\\.\\//, \"\"); // Strip leading './'\n\t\t}\n\n\t\t// send back the fixed url(...)\n\t\treturn \"url(\" + JSON.stringify(newUrl) + \")\";\n\t});\n\n\t// send back the fixed css\n\treturn fixedCss;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/style-loader/lib/urls.js\n// module id = 11\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 10l8 6-1-3.982c3.417 0 8.616.869 10 3.982 0-5.983-6.601-7.96-10-7.96 0-.85 1-3.32 1-4.04l-8 6z\\\" fill=\\\"#454545\\\" fill-rule=\\\"evenodd\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-undo/theme/icons/undo.svg\n// module id = 12\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M10 16l1-3.982c-3.417 0-8.616.869-10 3.982 0-5.983 6.601-7.96 10-7.96 0-.85-1-3.32-1-4.04l8 6-8 6z\\\" fill=\\\"#454545\\\" fill-rule=\\\"evenodd\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-undo/theme/icons/redo.svg\n// module id = 13\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M15.135 10.409c.361.248.654.56.88.934.225.375.338.816.338 1.324 0 .609-.128 1.123-.385 1.543-.256.42-.624.751-1.103.994a5.908 5.908 0 0 1-1.755.55c-.663.107-1.442.16-2.338.16H4.539v-.66a22.5 22.5 0 0 0 .66-.076c.265-.033.45-.073.558-.118.208-.085.35-.196.427-.334.076-.138.114-.317.114-.537V5.732c0-.203-.031-.372-.093-.507s-.211-.254-.448-.355a3.326 3.326 0 0 0-.61-.182 14.136 14.136 0 0 0-.608-.114v-.66h6.52c1.64 0 2.825.226 3.552.677.727.45 1.09 1.116 1.09 1.995 0 .406-.08.763-.244 1.07a2.388 2.388 0 0 1-.702.8 4.214 4.214 0 0 1-.99.54c-.383.153-.795.28-1.234.381v.16c.44.046.896.143 1.37.292.473.15.885.343 1.234.58zm-2.723-3.611c0-.665-.187-1.184-.562-1.556-.375-.372-.937-.558-1.687-.558-.107 0-.247.004-.419.012l-.444.021v4.449h.44c.913 0 1.587-.213 2.021-.639.434-.425.651-1.002.651-1.73zm.592 5.759c0-.835-.248-1.475-.744-1.92-.496-.445-1.21-.668-2.14-.668a22.977 22.977 0 0 0-.82.034v4.389c.05.208.209.385.474.528.265.144.586.216.964.216.67 0 1.216-.225 1.636-.676.42-.452.63-1.086.63-1.903z\\\" fill=\\\"#454545\\\" fill-rule=\\\"evenodd\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-basic-styles/theme/icons/bold.svg\n// module id = 14\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M13.825 3.914l-.126.558a5.701 5.701 0 0 0-.685.076c-.282.045-.49.088-.626.127-.237.073-.406.186-.508.338a1.586 1.586 0 0 0-.22.5l-2.03 8.769a1.24 1.24 0 0 0-.034.27c.001.13.03.24.086.33.056.09.157.17.304.237.085.04.27.086.558.14.288.053.502.086.643.097l-.127.558H5.656l.127-.558.677-.05c.293-.023.501-.057.625-.102a1.11 1.11 0 0 0 .5-.326c.112-.138.188-.306.228-.503l2.02-8.778a1.428 1.428 0 0 0 .035-.305.59.59 0 0 0-.072-.295c-.048-.085-.148-.161-.3-.229a3.457 3.457 0 0 0-.622-.19 5.001 5.001 0 0 0-.58-.106l.128-.558h5.403z\\\" fill=\\\"#454545\\\" fill-rule=\\\"evenodd\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-basic-styles/theme/icons/italic.svg\n// module id = 15\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M12.061 15.51v-.882c1.395-.847 2.345-1.633 2.85-2.358.37-.533.554-1.162.554-1.887 0-.437-.082-.759-.246-.964-.15-.205-.328-.307-.533-.307-.137 0-.328.048-.574.143-.37.123-.67.185-.902.185-.547 0-1.033-.205-1.456-.615-.424-.41-.636-.923-.636-1.538 0-.698.212-1.238.636-1.62a3.002 3.002 0 0 1 2.05-.78c.93 0 1.757.39 2.482 1.17.724.778 1.087 1.742 1.087 2.89 0 1.614-.602 3.084-1.805 4.41-.807.875-1.976 1.593-3.507 2.153zm-8.386 0v-.882c1.394-.847 2.345-1.633 2.85-2.358.37-.533.554-1.162.554-1.887 0-.437-.082-.759-.246-.964-.15-.205-.328-.307-.533-.307-.137 0-.328.048-.574.143-.37.123-.67.185-.903.185-.547 0-1.032-.205-1.456-.615-.424-.41-.636-.923-.636-1.538 0-.698.212-1.238.636-1.62a3.002 3.002 0 0 1 2.051-.78c.93 0 1.757.39 2.481 1.17.725.778 1.087 1.742 1.087 2.89 0 1.614-.601 3.084-1.804 4.41-.807.875-1.976 1.593-3.507 2.153z\\\" fill=\\\"#454545\\\" fill-rule=\\\"evenodd\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/theme/icons/quote.svg\n// module id = 16\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-block-quote/theme/theme.scss\n// module id = 17\n// module chunks = 0","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \"blockquote{border-left:5px solid #ccc;padding-left:20px;margin-left:0;font-style:italic;overflow:hidden}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-block-quote/theme/theme.scss\n// module id = 18\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-widget/theme/theme.scss\n// module id = 19\n// module chunks = 0","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \".ck-widget{margin:.8em 0;padding:0}.ck-widget.ck-widget_selected,.ck-widget.ck-widget_selected:hover{outline:3px solid #48a3f5}.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected{outline:3px solid #ddd}.ck-widget:hover{outline:3px solid #ffd25c}.ck-widget .ck-editable{border:1px solid transparent}.ck-widget .ck-editable.ck-editable_focused,.ck-widget .ck-editable:focus{outline:none;border:1px solid #48a3f5;box-shadow:inset 2px 2px 3px rgba(0,0,0,.1);background-color:#fff}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-widget/theme/theme.scss\n// module id = 20\n// module chunks = 0","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\" stroke-linejoin=\\\"round\\\" stroke-miterlimit=\\\"1.414\\\"><path d=\\\"M5.414 6.749L2.903 4.237a.49.49 0 1 1 .694-.694L6.394 6.34a10.662 10.662 0 0 1 2.127-.53c.366-.051.734-.081 1.103-.095a10.628 10.628 0 0 1 1.524.07c1.109.134 2.204.449 3.243.936a9.65 9.65 0 0 1 2.12 1.331c.276.231.542.484.784.766.18.211.349.439.488.692.169.307.301.664.301 1.039 0 .375-.132.732-.301 1.039a4.143 4.143 0 0 1-.488.691 6.668 6.668 0 0 1-.784.767 9.628 9.628 0 0 1-2.092 1.318l2.196 2.197a.49.49 0 1 1-.694.694l-2.485-2.484-.008.003-.931-.931.009-.003-6.215-6.215a9.887 9.887 0 0 0-.945.444l6.239 6.24-.006.005.78.78c-.388.094-.78.166-1.174.215l-1.11-1.11h.011L4.483 8.596a7.2 7.2 0 0 0-.665.514l-.112.098 4.897 4.897-.005.006 1.276 1.276a10.164 10.164 0 0 1-1.477-.117l-.479-.479-.009.009-4.863-4.863-.022.031a2.563 2.563 0 0 0-.124.2 1.497 1.497 0 0 0-.108.241.534.534 0 0 0-.028.133.29.29 0 0 0 .008.072.927.927 0 0 0 .082.226 2.613 2.613 0 0 0 .234.379l3.463 3.594a10.565 10.565 0 0 1-2.125-1 9.096 9.096 0 0 1-1.015-.721 6.672 6.672 0 0 1-.798-.764 4.325 4.325 0 0 1-.502-.69c-.184-.319-.329-.693-.329-1.089 0-.375.131-.732.301-1.039.139-.253.307-.481.488-.692.225-.263.471-.5.728-.719a9.538 9.538 0 0 1 2.096-1.341l.019-.009zm6.674.401a4.632 4.632 0 0 1 1.108 5.992l.345.344.046-.018a9.313 9.313 0 0 0 2-1.112 6.86 6.86 0 0 0 .727-.613c.137-.134.27-.277.392-.431.072-.091.141-.185.203-.286a1.966 1.966 0 0 0 .148-.292.72.72 0 0 0 .036-.12.29.29 0 0 0 .008-.072.492.492 0 0 0-.028-.133.999.999 0 0 0-.036-.096 2.165 2.165 0 0 0-.071-.145 2.917 2.917 0 0 0-.125-.2 3.592 3.592 0 0 0-.263-.335 5.444 5.444 0 0 0-.53-.523 7.955 7.955 0 0 0-1.054-.768 9.766 9.766 0 0 0-1.879-.891 10.119 10.119 0 0 0-1.027-.301zm-2.85.21l-.069.002a.508.508 0 0 0-.254.097.496.496 0 0 0-.104.679.498.498 0 0 0 .326.199l.045.005c.091.003.181.003.272.012a2.449 2.449 0 0 1 2.017 1.513c.024.061.043.125.069.185a.494.494 0 0 0 .45.287h.008a.496.496 0 0 0 .35-.158.482.482 0 0 0 .13-.335.638.638 0 0 0-.048-.219 3.379 3.379 0 0 0-.36-.723 3.438 3.438 0 0 0-2.791-1.543l-.028-.001h-.013z\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/theme/icons/low-vision.svg\n// module id = 21\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../../node_modules/css-loader/index.js??ref--1-1!../../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../../node_modules/css-loader/index.js??ref--1-1!../../../../node_modules/sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../../node_modules/css-loader/index.js??ref--1-1!../../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/theme/imagetextalternative/theme.scss\n// module id = 22\n// module chunks = 0","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \".cke-text-alternative-form{padding:1.2em;overflow:hidden}.cke-text-alternative-form:focus{outline:none}.cke-text-alternative-form .ck-label{margin-bottom:.4em}.cke-text-alternative-form__actions{clear:both;padding-top:1.2em}.cke-text-alternative-form__actions .ck-button{float:right}.cke-text-alternative-form__actions .ck-button+.ck-button{margin-right:.64em}.cke-text-alternative-form__actions .ck-button+.ck-button+.ck-button{float:left}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-image/theme/imagetextalternative/theme.scss\n// module id = 23\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/theme/theme.scss\n// module id = 24\n// module chunks = 0","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \".ck-editor__editable .image{text-align:center;clear:both}.ck-editor__editable .image.image-style-align-center,.ck-editor__editable .image.image-style-align-left,.ck-editor__editable .image.image-style-align-right,.ck-editor__editable .image.image-style-side{max-width:50%}.ck-editor__editable .image.image-style-side{float:right;margin-left:2em}.ck-editor__editable .image.image-style-align-left{float:left;margin-right:2em}.ck-editor__editable .image.image-style-align-center{margin-left:auto;margin-right:auto}.ck-editor__editable .image.image-style-align-right{float:right;margin-left:2em}.ck-editor__editable .image>img{display:block;margin:0 auto;max-width:100%}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-image/theme/theme.scss\n// module id = 25\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 14.994C2 16.102 2.895 17 3.994 17h12.012A2 2 0 0 0 18 14.994V5.006A2.001 2.001 0 0 0 16.006 3H3.994A2 2 0 0 0 2 5.006v9.988zm1-9.992C3 4.45 3.45 4 4.007 4h11.986A1.01 1.01 0 0 1 17 5.002v9.996C17 15.55 16.55 16 15.993 16H4.007A1.01 1.01 0 0 1 3 14.998V5.002zm1.024 10H16v-3.096l-2.89-4.263-3.096 5.257-3.003-2.103L4 13.96l.024 1.043zM6.406 6A1.4 1.4 0 0 0 5 7.393a1.4 1.4 0 0 0 1.406 1.393 1.4 1.4 0 0 0 1.407-1.393A1.4 1.4 0 0 0 6.406 6z\\\" fill=\\\"#454545\\\" fill-rule=\\\"evenodd\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/theme/icons/image.svg\n// module id = 26\n// module chunks = 0","module.exports = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 700 250\\\"><g fill=\\\"none\\\" fill-rule=\\\"evenodd\\\"><rect width=\\\"700\\\" height=\\\"250\\\" fill=\\\"#F7F7F7\\\" rx=\\\"4\\\"/><text fill=\\\"#5F6F77\\\" font-family=\\\"Arial,sans-serif\\\" font-size=\\\"24\\\"><tspan x=\\\"247.9\\\" y=\\\"135\\\">Uploading image…</tspan></text></g></svg>\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/theme/icons/image_placeholder.svg\n// module id = 27\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./imageuploadprogress.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./imageuploadprogress.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./imageuploadprogress.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-upload/theme/imageuploadprogress.scss\n// module id = 28\n// module chunks = 0","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \"figure.image{position:relative;overflow:hidden}figure.image.ck-appear{animation:fadeIn .7s}figure.image.ck-infinite-progress:before{content:\\\"\\\";width:30px;height:2px;position:absolute;top:0;right:0;background:rgba(0,0,0,.1);animation-name:readingProgressAnimation;animation-duration:1.5s;animation-iteration-count:infinite;transition-timing-function:linear}figure.image.ck-image-upload-placeholder>img{width:100%}figure.image .ck-progress-bar{height:2px;width:0;position:absolute;top:0;left:0;background:#6ab5f9;transition:width .1s}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes readingProgressAnimation{0%{width:30px;right:0}50%{width:45px}to{right:100%}}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-upload/theme/imageuploadprogress.scss\n// module id = 29\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-heading/theme/theme.scss\n// module id = 30\n// module chunks = 0","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \".ck-heading_heading1{font-size:1.5em}.ck-heading_heading2{font-size:1.3em}.ck-heading_heading3{font-size:1.1em}[class*=ck-heading_]{line-height:21.6px;padding:9.6px}[class*=ck-heading_heading]{font-weight:700}.ck-dropdown.ck-heading-dropdown .ck-dropdown__button .ck-button__label{width:8em}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-heading/theme/theme.scss\n// module id = 31\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./placeholder.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./placeholder.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./placeholder.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-engine/theme/placeholder.scss\n// module id = 32\n// module chunks = 0","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \".ck-placeholder:before{content:attr(data-placeholder);cursor:text;color:#c2c2c2;pointer-events:none}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-engine/theme/placeholder.scss\n// module id = 33\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../../node_modules/css-loader/index.js??ref--1-1!../../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../../node_modules/css-loader/index.js??ref--1-1!../../../../node_modules/sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../../node_modules/css-loader/index.js??ref--1-1!../../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-image/theme/imagecaption/theme.scss\n// module id = 34\n// module chunks = 0","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \".ck-editor__editable .image>figcaption{color:#333;background-color:#f7f7f7;padding:.8em;font-size:.75em;outline-offset:-1px}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-image/theme/imagecaption/theme.scss\n// module id = 35\n// module chunks = 0","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 16h16v1H2v-1zm15-2H3V6h14v8zm-1-7H4v6h12V7zM2 3h16v1H2V3z\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/theme/icons/object-full-width.svg\n// module id = 36\n// module chunks = 0","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 15h16v1H2v-1zm11-3h5v1h-5v-1zm-2 1H2V6h9v7zm-1-6H3v5h7V7zm3 2h5v1h-5V9zm0-3h5v1h-5V6zM2 3h16v1H2V3z\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/theme/icons/object-left.svg\n// module id = 37\n// module chunks = 0","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\" stroke-linejoin=\\\"round\\\" stroke-miterlimit=\\\"1.414\\\"><path d=\\\"M2 15h16v1H2v-1zm13-2H5V6h10v7zm-1-6H6v5h8V7zM2 3h16v1H2V3z\\\" fill-rule=\\\"nonzero\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/theme/icons/object-center.svg\n// module id = 38\n// module chunks = 0","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M18 16H2v-1h16v1zM6.978 13H2v-1h4.978v1zM18 6v7H9V6h9zm-1 6V7h-7v5h7zM6.978 10H2V9h4.978v1zm0-3H2V6h4.978v1zM18 4H2V3h16v1z\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-core/theme/icons/object-right.svg\n// module id = 39\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><g fill=\\\"#222\\\" fill-rule=\\\"evenodd\\\"><path d=\\\"M14.2 10.956l1.227-1.227a3.995 3.995 0 0 0-.002-5.654 4 4 0 0 0-5.654-.002L7.698 6.145a3.995 3.995 0 0 0 .003 5.654c.39.39.84.682 1.32.878l-.305-.307.638-.638a2.99 2.99 0 0 1-.946-.64 2.995 2.995 0 0 1-.003-4.24l2.073-2.072a3 3 0 0 1 4.242 4.242l-1.226 1.227.707.707z\\\"/><path d=\\\"M10.166 7.405c.41.192.795.457 1.133.796a3.995 3.995 0 0 1 .003 5.654l-2.073 2.072a4 4 0 0 1-5.654-.002 3.995 3.995 0 0 1-.002-5.654l1.362-1.363.707.707-1.362 1.363a3 3 0 0 0 4.243 4.243l2.072-2.073a2.995 2.995 0 0 0-.003-4.24 2.987 2.987 0 0 0-1.196-.733l.77-.77z\\\"/></g></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/theme/icons/link.svg\n// module id = 40\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// Prepare cssTransformation\nvar transform;\n\nvar options = {}\noptions.transform = transform\n// add the styles to the DOM\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--1-1!../../../node_modules/sass-loader/lib/loader.js!./theme.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-link/theme/theme.scss\n// module id = 41\n// module chunks = 0","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \".ck-link-form{padding:1.2em;overflow:hidden}.ck-link-form:focus{outline:none}.ck-link-form .ck-input-text{width:100%}.ck-link-form .ck-label{margin-bottom:.2em}.ck-link-form__actions{clear:both;padding-top:1.2em}.ck-link-form__actions .ck-button{float:right}.ck-link-form__actions .ck-button+.ck-button{margin-right:.64em}.ck-link-form__actions .ck-button:last-child{float:left;margin-right:2.56em}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /workspace/ckeditor5/node_modules/css-loader?{\"minimize\":true}!/workspace/ckeditor5/node_modules/sass-loader/lib/loader.js!../ckeditor5-link/theme/theme.scss\n// module id = 42\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 17h10v-1H7v1zM6 4v1h13V4H6zm1 6v1h11v-1H7zM2 2.5c0 .277.223.5.5.5H3v3.5a.499.499 0 1 0 1 0v-4c0-.277-.223-.5-.5-.5h-1c-.277 0-.5.223-.5.5zM2.5 8a.499.499 0 1 0 0 1H4v1H2.5c-.277 0-.5.223-.5.5v2c0 .277.223.5.5.5h2a.499.499 0 1 0 0-1H3v-1h1.5a.46.46 0 0 0 .188-.031.45.45 0 0 0 .28-.281A.461.461 0 0 0 5 10.5v-2a.46.46 0 0 0-.031-.187.45.45 0 0 0-.282-.282.463.463 0 0 0-.125-.03H2.5V8zm2.352 10.853a.493.493 0 0 0 .148-.35v-4.005A.493.493 0 0 0 4.505 14h-2.01a.494.494 0 0 0-.495.5c0 .268.222.5.495.5H4v1H2.495a.494.494 0 0 0-.495.5c0 .268.222.5.495.5H4v1H2.495a.494.494 0 0 0-.495.5c0 .268.222.5.495.5h2.01a.49.49 0 0 0 .351-.146z\\\" fill=\\\"#454545\\\" fill-rule=\\\"evenodd\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-list/theme/icons/numberedlist.svg\n// module id = 43\n// module chunks = 0","module.exports = \"<svg width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M6 16v1h10v-1H6zM6 4v1h12V4H6zm0 6v1h11v-1H6zM1 4.5C1 3.672 1.666 3 2.5 3 3.328 3 4 3.666 4 4.5 4 5.328 3.334 6 2.5 6 1.672 6 1 5.334 1 4.5zm0 6C1 9.672 1.666 9 2.5 9c.828 0 1.5.666 1.5 1.5 0 .828-.666 1.5-1.5 1.5-.828 0-1.5-.666-1.5-1.5zm0 6c0-.828.666-1.5 1.5-1.5.828 0 1.5.666 1.5 1.5 0 .828-.666 1.5-1.5 1.5-.828 0-1.5-.666-1.5-1.5z\\\" fill=\\\"#454545\\\" fill-rule=\\\"evenodd\\\"/></svg>\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../ckeditor5-list/theme/icons/bulletedlist.svg\n// module id = 44\n// module chunks = 0"],"sourceRoot":""}