mirror of
https://github.com/zadam/trilium.git
synced 2024-11-18 05:35:56 +08:00
1 line
No EOL
2.4 MiB
1 line
No EOL
2.4 MiB
{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap c0686b2f4b7e42b55900","webpack:///./node_modules/css-loader/lib/css-base.js","webpack:///./node_modules/style-loader/lib/addStyles.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_root.js","webpack:///(webpack)/buildin/harmony-module.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/log.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/translation-service.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/locale.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/mix.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/spy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/uid.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/priorities.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/emittermixin.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/eq.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseKeysIn.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/objecttomap.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/tomap.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/node.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/isiterable.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/element.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/treewalker.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/last.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/comparearrays.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/position.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_ListCache.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_Hash.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_MapCache.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_Stack.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_getSymbols.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_getTag.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseClone.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/matcher.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/element.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/textproxy.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/containerelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/editableelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/range.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/mapper.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/documentfragment.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/modelconversiondispatcher.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/attributeelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/emptyelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/env.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/keyboard.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/uielement.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/documentfragment.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/writer.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/model-to-view-converters.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/writer.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/viewconversiondispatcher.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/view-to-model-converters.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/liveposition.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/controller/insertcontent.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/controller/deletecontent.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/unicode.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/controller/modifyselection.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/controller/getselectedcontent.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/controller/datacontroller.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_SetCache.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseIsEqual.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/batch.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/attributedelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/movedelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/removedelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/renamedelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/transform.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseSlice.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseFlatten.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/memoize.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/transform.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/markerdelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/basic-transformations.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/rootelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/liverange.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/mapsequal.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/selection.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/documentselection.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/schema.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/markercollection.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/document.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editor/editor.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/isdomnode.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/emittermixin.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/keystrokehandler.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/count.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/selection.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/filler.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/diff.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/insertat.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/remove.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/renderer.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/global.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/indexof.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/getancestors.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/getcommonancestor.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/domconverter.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/rooteditableelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/fakeselectionobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/isrange.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/iswindow.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isElement.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/getborderwidths.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/rect.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/scroll.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/document.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/view-selection-to-model-converters.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/model-selection-to-view-converters.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/controller/editingcontroller.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/getdatafromelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/setdatainelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editor/standardeditor.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/viewcollection.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/cloneDeepWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/template.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/view.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/getpositionedancestor.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/position.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/dom/tounit.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/first.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/focuscycler.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarseparatorview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/bindings/preventdefault.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/normalizetoolbarconfig.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/componentfactory.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/enabletoolbarkeyboardfocus.js","webpack:///./node_modules/@ckeditor/ckeditor5-editor-balloon/src/ballooneditorui.js","webpack:///./node_modules/@ckeditor/ckeditor5-clipboard/src/datatransfer.js","webpack:///./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.js","webpack:///./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js","webpack:///./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.js","webpack:///./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.js","webpack:///./node_modules/@ckeditor/ckeditor5-enter/src/entercommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-enter/src/enterobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/difftochanges.js","webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/changebuffer.js","webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/input.js","webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/deletecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-undo/src/basecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-undo/src/undocommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js","webpack:///./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-autoformat/src/autoformat.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter.js","webpack:///./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteengine.js","webpack:///./node_modules/@ckeditor/ckeditor-cloudservices-core/src/uploadgateway/fileuploader.js","webpack:///./node_modules/@ckeditor/ckeditor-cloudservices-core/src/uploadgateway/uploadgateway.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/converters.js","webpack:///./node_modules/@ckeditor/ckeditor5-widget/src/highlightstack.js","webpack:///./node_modules/@ckeditor/ckeditor5-widget/src/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/imageengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-widget/src/widget.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/label/labelview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/bindings/submithandler.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/ui/textalternativeformview.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image/ui/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/imageuploadengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/ui/filedialogbuttonview.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/imageuploadprogress.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/imageupload.js","webpack:///./node_modules/@ckeditor/ckeditor5-paragraph/src/paragraphcommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-paragraph/src/paragraph.js","webpack:///./node_modules/@ckeditor/ckeditor5-heading/src/headingcommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-heading/src/headingengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/createdropdown.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/list/createlistdropdown.js","webpack:///./node_modules/@ckeditor/ckeditor5-heading/src/heading.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/placeholder.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagecaption/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagestyle/converters.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestyleengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagestyle.js","webpack:///./node_modules/@ckeditor/ckeditor5-link/src/findlinkrange.js","webpack:///./node_modules/@ckeditor/ckeditor5-link/src/linkcommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-link/src/link.js","webpack:///./node_modules/@ckeditor/ckeditor5-list/src/listcommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-list/src/indentcommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-list/src/viewlistitemelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-list/src/converters.js","webpack:///./node_modules/@ckeditor/ckeditor5-list/src/listengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/rest.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_getPrototype.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_isHostObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isObjectLike.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isPlainObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/config.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/plugincollection.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/eventinfo.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_assignValue.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_copyObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseProperty.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_getLength.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isFunction.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isLength.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isArrayLike.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_isIndex.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_isIterateeCall.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_apply.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isSymbol.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/toNumber.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/toFinite.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/toInteger.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_createAssigner.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_isPrototype.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_Reflect.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_iteratorToArray.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseTimes.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isArrayLikeObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isArguments.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isArray.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isString.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_indexKeys.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/keysIn.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/assignIn.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/extend.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/text.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/textproxy.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/nodelist.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/range.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_listCacheClear.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_assocIndexOf.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_listCacheDelete.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_listCacheGet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_listCacheHas.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_listCacheSet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_stackClear.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_toSource.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isNative.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_getNative.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_nativeCreate.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_hashClear.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_hashGet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_hashHas.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_hashDelete.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_hashSet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_Map.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_mapCacheClear.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_getMapData.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_isKeyable.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_mapCacheDelete.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_mapCacheGet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_mapCacheHas.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_mapCacheSet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_stackSet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_stackDelete.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_stackGet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_stackHas.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_arrayEach.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseHas.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseKeys.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/keys.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseAssign.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cloneBuffer.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_copyArray.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_copySymbols.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_arrayPush.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseGetAllKeys.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_getAllKeys.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_DataView.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_Promise.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_Set.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_WeakMap.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_initCloneArray.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_Uint8Array.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cloneArrayBuffer.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cloneDataView.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_addMapEntry.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_arrayReduce.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_mapToArray.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cloneMap.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cloneRegExp.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_addSetEntry.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_setToArray.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cloneSet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_Symbol.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cloneSymbol.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cloneTypedArray.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_initCloneByTag.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseCreate.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_initCloneObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/clone.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/node.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/text.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/treewalker.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/position.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/modelconsumable.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/viewconsumable.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/operation.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_setCacheAdd.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_setCacheHas.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_arraySome.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_equalArrays.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_equalByTag.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_equalObjects.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isTypedArray.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseIsEqualDeep.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isEqual.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/attributeoperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/moveoperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/reinsertoperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/removeoperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/insertoperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/markeroperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/nooperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/renameoperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/rootattributeoperation.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/operationfactory.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/deltafactory.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/delta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/insertdelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/splitdelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/mergedelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/wrapdelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/unwrapdelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/weakinsertdelta.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/delta/basic-deltas.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/chunk.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_isFlattenable.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/concat.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseIndexOf.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_indexOfNaN.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_arrayIncludes.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_arrayIncludesWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_arrayMap.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseUnary.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_cacheHas.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseDifference.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/difference.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseIsMatch.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_isStrictComparable.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseToPairs.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_setToPairs.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_createToPairs.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/toPairs.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_getMatchData.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_matchesStrictComparable.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseMatches.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseToString.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/toString.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_stringToPath.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_castPath.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_isKey.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_toKey.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseGet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/get.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseHasIn.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_hasPath.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/hasIn.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseMatchesProperty.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/identity.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_basePropertyDeep.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/property.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseIteratee.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/differenceBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/differenceWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/drop.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/dropRight.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseWhile.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/dropRightWhile.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/toLength.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseClamp.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseFill.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/fill.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/findIndex.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseFindIndex.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/flatten.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/head.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_castArrayLikeObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseIntersection.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/intersection.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/intersectionBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/intersectionWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/join.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/nth.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseNth.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_basePullAll.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseIndexOfWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/pullAll.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/pull.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/pullAllBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_parent.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseAt.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_basePullAt.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_compareAscending.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/pullAt.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/remove.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/reverse.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseSortedIndex.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseSortedIndexBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/sortedIndex.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/sortedUniq.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseSortedUniq.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_createSet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseUniq.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/noop.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/union.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/unionBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/unionWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/uniq.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/unzip.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_arrayFilter.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/unzipWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/without.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseXor.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/xor.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/xorBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/xorWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/zip.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseZipObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/zipObject.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/zipObjectDeep.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_baseSet.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/zipWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/array.default.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/compact.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/dropWhile.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/findLastIndex.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/flattenDeep.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/flattenDepth.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/fromPairs.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/indexOf.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/initial.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/lastIndexOf.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/pullAllWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/slice.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/sortedIndexBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/sortedIndexOf.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/sortedLastIndex.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/sortedLastIndexBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/sortedLastIndexOf.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/sortedUniqBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/tail.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/take.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/takeRight.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/takeRightWhile.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/takeWhile.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/uniqBy.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/uniqWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/array.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/history.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/observer.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isEqualWith.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mutationobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/now.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/debounce.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/selectionobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventdata.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/focusobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/keyobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/basichtmlwriter.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/collection.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/focustracker.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/editorui/editoruiview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/editableui/editableuiview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview.js","webpack:///./node_modules/@ckeditor/ckeditor5-editor-balloon/src/ballooneditoruiview.js","webpack:///./node_modules/@ckeditor/ckeditor5-editor-balloon/src/ballooneditor.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack:///./node_modules/@ckeditor/ckeditor5-enter/src/enter.js","webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/inputcommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/deleteobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/delete.js","webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/typing.js","webpack:///./node_modules/@ckeditor/ckeditor5-undo/src/redocommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-undo/src/undoengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/icon/iconview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/tooltip/tooltipview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.js","webpack:///./node_modules/@ckeditor/ckeditor5-undo/src/undo.js","webpack:///./node_modules/@ckeditor/ckeditor5-essentials/src/essentials.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/filereader.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/filerepository.js","webpack:///./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-basic-styles/src/boldengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.js","webpack:///./node_modules/@ckeditor/ckeditor5-basic-styles/src/italicengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.js","webpack:///./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.js","webpack:///./node_modules/@ckeditor/ckeditor-cloudservices-core/src/token/token.js","webpack:///./node_modules/@ckeditor/ckeditor5-cloudservices/src/cloudservices.js","webpack:///./node_modules/@ckeditor/ckeditor5-easy-image/src/cloudservicesuploadadapter.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/inputtext/inputtextview.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/image.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/imageuploadcommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/notification/notification.js","webpack:///./node_modules/@ckeditor/ckeditor5-upload/src/imageuploadbutton.js","webpack:///./node_modules/@ckeditor/ckeditor5-easy-image/src/easyimage.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/model.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/list/listview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/list/listitemview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/dropdownview.js","webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/dropdownpanelview.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagecaption.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestylecommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-image/src/imagetoolbar.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/clickobserver.js","webpack:///./node_modules/@ckeditor/ckeditor5-link/src/linkelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-link/src/unlinkcommand.js","webpack:///./node_modules/@ckeditor/ckeditor5-link/src/linkengine.js","webpack:///./node_modules/@ckeditor/ckeditor5-link/src/ui/linkformview.js","webpack:///./node_modules/@ckeditor/ckeditor5-list/src/list.js","webpack:///./src/inserttext.js","webpack:///./src/ckeditor.js","webpack:///(webpack)/buildin/global.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_checkGlobal.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/isBuffer.js","webpack:///./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/constant.js","webpack:///./node_modules/@ckeditor/ckeditor5-editor-balloon/theme/theme.scss?78e4","webpack:///./node_modules/@ckeditor/ckeditor5-editor-balloon/theme/theme.scss","webpack:///./node_modules/style-loader/lib/urls.js","webpack:///./node_modules/@ckeditor/ckeditor5-undo/theme/icons/undo.svg","webpack:///./node_modules/@ckeditor/ckeditor5-undo/theme/icons/redo.svg","webpack:///./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/bold.svg","webpack:///./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/italic.svg","webpack:///./node_modules/@ckeditor/ckeditor5-core/theme/icons/quote.svg","webpack:///./node_modules/@ckeditor/ckeditor5-block-quote/theme/theme.scss?45fe","webpack:///./node_modules/@ckeditor/ckeditor5-block-quote/theme/theme.scss","webpack:///./node_modules/@ckeditor/ckeditor5-widget/theme/theme.scss?ed1b","webpack:///./node_modules/@ckeditor/ckeditor5-widget/theme/theme.scss","webpack:///./node_modules/@ckeditor/ckeditor5-core/theme/icons/low-vision.svg","webpack:///./node_modules/@ckeditor/ckeditor5-image/theme/imagetextalternative/theme.scss?6d68","webpack:///./node_modules/@ckeditor/ckeditor5-image/theme/imagetextalternative/theme.scss","webpack:///./node_modules/@ckeditor/ckeditor5-image/theme/theme.scss?1d4d","webpack:///./node_modules/@ckeditor/ckeditor5-image/theme/theme.scss","webpack:///./node_modules/@ckeditor/ckeditor5-core/theme/icons/image.svg","webpack:///./node_modules/@ckeditor/ckeditor5-upload/theme/icons/image_placeholder.svg","webpack:///./node_modules/@ckeditor/ckeditor5-upload/theme/imageuploadprogress.scss?3816","webpack:///./node_modules/@ckeditor/ckeditor5-upload/theme/imageuploadprogress.scss","webpack:///./node_modules/@ckeditor/ckeditor5-heading/theme/theme.scss?83ab","webpack:///./node_modules/@ckeditor/ckeditor5-heading/theme/theme.scss","webpack:///./node_modules/@ckeditor/ckeditor5-engine/theme/placeholder.scss?5244","webpack:///./node_modules/@ckeditor/ckeditor5-engine/theme/placeholder.scss","webpack:///./node_modules/@ckeditor/ckeditor5-image/theme/imagecaption/theme.scss?d792","webpack:///./node_modules/@ckeditor/ckeditor5-image/theme/imagecaption/theme.scss","webpack:///./node_modules/@ckeditor/ckeditor5-core/theme/icons/object-full-width.svg","webpack:///./node_modules/@ckeditor/ckeditor5-core/theme/icons/object-left.svg","webpack:///./node_modules/@ckeditor/ckeditor5-core/theme/icons/object-center.svg","webpack:///./node_modules/@ckeditor/ckeditor5-core/theme/icons/object-right.svg","webpack:///./node_modules/@ckeditor/ckeditor5-link/theme/icons/link.svg","webpack:///./node_modules/@ckeditor/ckeditor5-link/theme/theme.scss?541b","webpack:///./node_modules/@ckeditor/ckeditor5-link/theme/theme.scss","webpack:///./node_modules/@ckeditor/ckeditor5-list/theme/icons/numberedlist.svg","webpack:///./node_modules/@ckeditor/ckeditor5-list/theme/icons/bulletedlist.svg"],"names":[],"mappings":";;;;AAAA,cACA,2BACA,uCACA,sCACA,IACA,aACA,+CAEA,oBACA,GAAC,iDACD,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,EClHA,ECuBA,qCAEA,SACA,SAmBA,iDD3CA,gBACA,OACA,cAEA,sCACA,kBAAqC,CAErC,+CACA,UAEA,+BACA,SAEA,4CACA,UACA,CCIA,WAyBA,SACA,CAYA,0GACA,CAQA,uFCrEA,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})(typeof self !== 'undefined' ? self : 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 c0686b2f4b7e42b55900","/*\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// ./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// ./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// ./node_modules/@ckeditor/ckeditor5-utils/src/lib/lodash/_root.js\n// module id = 2\n// module chunks = 0","module.exports = function(originalModule) {\r\n\tif(!originalModule.webpackPolyfill) {\r\n\t\tvar module = Object.create(originalModule);\r\n\t\t// module.parent = undefined by default\r\n\t\tif(!module.children) module.children = [];\r\n\t\tObject.defineProperty(module, \"loaded\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.l;\r\n\t\t\t}\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"id\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.i;\r\n\t\t\t}\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"exports\", {\r\n\t\t\tenumerable: true,\r\n\t\t});\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n};\r\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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 observable–attribute 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()` observable–attributes (`{ 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 * environment–specific 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 re–uses 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 ` ` 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 ` ` 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 ` ` if this is the last text node in its container,\n\t * * remaining spaces are replaced to a chain of spaces and ` ` (e.g. `'x x'` becomes `'x 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 ` `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 chars, that were in DOM text data because of rendering reasons, to spaces.\n\t\t// First, change all ` \\u00A0` pairs (space + ) 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 character that is at the beginning of the text node to space character.\n\t\t// As above, that 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 after `x` character.\n\t\t// We have to fix it. Since we already change all ` `, we will have something like this at the end of text data:\n\t\t// `x_ _ _` -> `x_ `. Find 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 .\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 created for rendering reasons should be\n\t\t// changed to normal space. All left are 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 upper–left 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 in–place 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// ./node_modules/@ckeditor/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 re–calculate 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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} (sub–templates),\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: 'static–text'\n *\t\t\t\t},\n *\t\t\t\t'also-static–text',\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// ./node_modules/@ckeditor/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} pre–configured 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// Auto–register 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 scroll–independent 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// ./node_modules/@ckeditor/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 pre–defined 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 event–driven.\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 non–collapsed 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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, '<' )\n\t\t.replace( />/g, '>' )\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/, ' ' )\n\t\t.replace( /\\s$/, ' ' )\n\t\t// Preserve other subsequent spaces now.\n\t\t.replace( /\\s\\s/g, ' ' );\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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 could’ve 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 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 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 , 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 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 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 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 `- ` – A paragraph will be changed to a bulleted list.\n\t * - `1. ` or `1) ` – 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**` – `**` characters are removed and `foobar` is set to bold,\n\t * - `__foobar__` – `__` characters are removed and `foobar` is set to bold,\n\t * - `*foobar*` – `*` characters are removed and `foobar` is set to italic,\n\t * - `_foobar_` – `_` characters are removed and `foobar` is set to italic,\n\t * - ``` `foobar` – ``` ` ``` 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 * * `> ` – 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 – That it starts in a text (or another node) which has the attribute set.\n\t\t * * If the selection is empty – 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 — 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./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// ./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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 – 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 non–default 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// ./node_modules/@ckeditor/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 full–width 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 user–defined 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 non–collapsed 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 two–way 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 2–way 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 icon–only 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 post–render 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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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 — `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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/ckeditor5-list/src/list.js\n// module id = null\n// module chunks = ","import Text from '@ckeditor/ckeditor5-engine/src/model/text';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nexport default class InserttextPlugin extends Plugin {\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\teditor.data.insertLink = function( linkText, linkHref ) {\n\t\t\tconst text = new Text( linkText, { linkHref } );\n\n\t\t\teditor.data.insertContent( text, editor.document.selection );\n\t\t};\n\n\t\teditor.data.insertText = function( str ) {\n\t\t\tconst text = new Text( str );\n\n\t\t\teditor.data.insertContent( text, editor.document.selection );\n\t\t};\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/inserttext.js\n// module id = null\n// module chunks = ","/**\n * @license Copyright (c) 2003-2018, 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';\nimport InserttextPlugin from './inserttext';\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\tInserttextPlugin\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;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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(\"!!../../../css-loader/index.js??ref--1-1!../../../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(\"!../../../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(\"!!../../../css-loader/index.js??ref--1-1!../../../sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../css-loader/index.js??ref--1-1!../../../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// ./node_modules/@ckeditor/ckeditor5-editor-balloon/theme/theme.scss\n// module id = 9\n// module chunks = 0","exports = module.exports = require(\"../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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// ./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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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(\"!!../../../css-loader/index.js??ref--1-1!../../../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(\"!../../../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(\"!!../../../css-loader/index.js??ref--1-1!../../../sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../css-loader/index.js??ref--1-1!../../../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// ./node_modules/@ckeditor/ckeditor5-block-quote/theme/theme.scss\n// module id = 17\n// module chunks = 0","exports = module.exports = require(\"../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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(\"!!../../../css-loader/index.js??ref--1-1!../../../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(\"!../../../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(\"!!../../../css-loader/index.js??ref--1-1!../../../sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../css-loader/index.js??ref--1-1!../../../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// ./node_modules/@ckeditor/ckeditor5-widget/theme/theme.scss\n// module id = 19\n// module chunks = 0","exports = module.exports = require(\"../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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(\"!!../../../../css-loader/index.js??ref--1-1!../../../../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(\"!../../../../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(\"!!../../../../css-loader/index.js??ref--1-1!../../../../sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../../css-loader/index.js??ref--1-1!../../../../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// ./node_modules/@ckeditor/ckeditor5-image/theme/imagetextalternative/theme.scss\n// module id = 22\n// module chunks = 0","exports = module.exports = require(\"../../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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(\"!!../../../css-loader/index.js??ref--1-1!../../../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(\"!../../../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(\"!!../../../css-loader/index.js??ref--1-1!../../../sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../css-loader/index.js??ref--1-1!../../../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// ./node_modules/@ckeditor/ckeditor5-image/theme/theme.scss\n// module id = 24\n// module chunks = 0","exports = module.exports = require(\"../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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(\"!!../../../css-loader/index.js??ref--1-1!../../../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(\"!../../../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(\"!!../../../css-loader/index.js??ref--1-1!../../../sass-loader/lib/loader.js!./imageuploadprogress.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../css-loader/index.js??ref--1-1!../../../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// ./node_modules/@ckeditor/ckeditor5-upload/theme/imageuploadprogress.scss\n// module id = 28\n// module chunks = 0","exports = module.exports = require(\"../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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(\"!!../../../css-loader/index.js??ref--1-1!../../../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(\"!../../../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(\"!!../../../css-loader/index.js??ref--1-1!../../../sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../css-loader/index.js??ref--1-1!../../../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// ./node_modules/@ckeditor/ckeditor5-heading/theme/theme.scss\n// module id = 30\n// module chunks = 0","exports = module.exports = require(\"../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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(\"!!../../../css-loader/index.js??ref--1-1!../../../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(\"!../../../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(\"!!../../../css-loader/index.js??ref--1-1!../../../sass-loader/lib/loader.js!./placeholder.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../css-loader/index.js??ref--1-1!../../../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// ./node_modules/@ckeditor/ckeditor5-engine/theme/placeholder.scss\n// module id = 32\n// module chunks = 0","exports = module.exports = require(\"../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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(\"!!../../../../css-loader/index.js??ref--1-1!../../../../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(\"!../../../../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(\"!!../../../../css-loader/index.js??ref--1-1!../../../../sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../../css-loader/index.js??ref--1-1!../../../../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// ./node_modules/@ckeditor/ckeditor5-image/theme/imagecaption/theme.scss\n// module id = 34\n// module chunks = 0","exports = module.exports = require(\"../../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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(\"!!../../../css-loader/index.js??ref--1-1!../../../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(\"!../../../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(\"!!../../../css-loader/index.js??ref--1-1!../../../sass-loader/lib/loader.js!./theme.scss\", function() {\n\t\t\tvar newContent = require(\"!!../../../css-loader/index.js??ref--1-1!../../../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// ./node_modules/@ckeditor/ckeditor5-link/theme/theme.scss\n// module id = 41\n// module chunks = 0","exports = module.exports = require(\"../../../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// ./node_modules/css-loader?{\"minimize\":true}!./node_modules/sass-loader/lib/loader.js!./node_modules/@ckeditor/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// ./node_modules/@ckeditor/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// ./node_modules/@ckeditor/ckeditor5-list/theme/icons/bulletedlist.svg\n// module id = 44\n// module chunks = 0"],"sourceRoot":""} |